E. Road to 1600 发表于 2020-04-10 | 阅读数 $rook$可以走上下左右,$queen$可以上下左右斜。每次找每个可走的最小的走。如果没走完跳跃到某个点继续走花费$1$。 构造$n\times n,rook<queen$。 $n<3,-1$ $n=3$,暴力$O(9!)$ $n>3$构造顺利走完除了$3\times 3$格子。 代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165#include <bits/stdc++.h>using namespace std;typedef long long ll;#define pii pair<int, int>#define mk make_pairconst int N = 1e3 + 10;const int mod = 1e9 + 7;int a[N][N], v[N][N];void dfs(int x, int y, bool qe){ v[x][y] = 1; int minn = 1e9, ansx, ansy; for (int i = 1; i <= 3; i++) if (v[x][i] == 0) { if (minn > a[x][i]) { minn = a[x][i]; ansx = x; ansy = i; } } for (int i = 1; i <= 3; i++) if (v[i][y] == 0) { if (minn > a[i][y]) { minn = a[i][y]; ansx = i; ansy = y; } } if (qe) { for (int i = -3; i <= 3; i++) { int xx = x + i; int yy = y + i; if (xx >= 1 && xx <= 3 && yy >= 1 && yy <= 3 && !v[xx][yy]) { if (minn > a[xx][yy]) { minn = a[xx][yy]; ansx = xx; ansy = yy; } } } for (int i = -3; i <= 3; i++) { int xx = x + i; int yy = y - i; if (xx >= 1 && xx <= 3 && yy >= 1 && yy <= 3 && !v[xx][yy]) { if (minn > a[xx][yy]) { minn = a[xx][yy]; ansx = xx; ansy = yy; } } } } if (minn == 1e9) return; dfs(ansx, ansy, qe);}int b[10];int vis[10];int ok = 0;void d(int x){ if (ok) return; if (x == 10) { for (int i = 1; i <= 9; i++) a[(i - 1) / 3 + 1][(i - 1) % 3 + 1] = b[i]; int ans1 = 0; for (int i = 1; i <= 3; i++) for (int j = 1; j <= 3; j++) v[i][j] = 0; for (int i = 1; i <= 3; i++) for (int j = 1; j <= 3; j++) if (v[i][j] == 0) ans1++, dfs(i, j, 0); int ans2 = 0; for (int i = 1; i <= 3; i++) for (int j = 1; j <= 3; j++) v[i][j] = 0; for (int i = 1; i <= 3; i++) for (int j = 1; j <= 3; j++) if (v[i][j] == 0) ans2++, dfs(i, j, 1); if (ans1 < ans2) { ok = 1; for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) cout << a[i][j] << " "; cout << endl; } } return; } for (int i = 2; i <= 9; i++) { if (vis[i] == 0) { b[x] = i; vis[i] = 1; d(x + 1); vis[i] = 0; } }}/*1 2 4 5 3 8 9 6 7 */int n;int main(){ // vis[1] = 1; // b[1] = 1; // d(2); scanf("%d", &n); if (n <= 2) return puts("-1"), 0; int t = n * n - 9, cur = 0; a[1][1] = t + 1; a[1][2] = t + 2; a[1][3] = t + 4; a[2][1] = t + 5; a[2][2] = t + 3; a[2][3] = t + 8; a[3][1] = t + 9; a[3][2] = t + 6; a[3][3] = t + 7; for (int i = n; i > 3; i--) { if (i & 1) { for (int j = 1; j <= i; j++) a[i][j] = ++cur; for (int j = i - 1; j >= 1; j--) a[j][i] = ++cur; } else { for (int j = 1; j < i; j++) a[j][i] = ++cur; for (int j = i; j >= 1; j--) a[i][j] = ++cur; } } for (int i = 1; i <= n; i++, puts("")) for (int j = 1; j <= n; j++) printf("%d ", a[i][j]); return 0;}