在 p×q 棋盤(p*q ≤ 26)上,騎士走「日」字(8 種方向)。求能否遍歷所有格子恰好一次,若能輸出字典序最小的路徑(格子名如 A1, B3...),否則輸出 impossible。
深度優先搜索 + 回溯:
#include <cstdio>
#include <cstring>
const int dx[8] = {-2,-2,-1,-1,1,1,2,2};
const int dy[8] = {-1,1,-2,2,-2,2,-1,1};
const char col[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char pathX[28]; int pathY[28];
int vis[28][28], p, q, total, step;
bool found;
void dfs(int x, int y, int cnt) {
if (cnt == total) { found = true; return; }
for (int i = 0; i < 8; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 0 || nx >= q || ny < 0 || ny >= p || vis[nx][ny]) continue;
vis[nx][ny] = 1;
dfs(nx, ny, cnt+1);
if (found) { pathX[step] = col[x]; pathY[step++] = y+1; return; }
vis[nx][ny] = 0;
}
}
int main() {
int T; scanf("%d", &T);
for (int cs = 1; cs <= T; cs++) {
scanf("%d %d", &p, &q);
total = p * q; step = 0; found = false;
memset(vis, 0, sizeof(vis));
vis[0][0] = 1;
dfs(0, 0, 1);
printf("Scenario #%d:\n", cs);
if (!found) puts("impossible");
else {
for (int i = step-1; i >= 0; i--) printf("%c%d", pathX[i], pathY[i]);
puts("");
}
if (cs < T) puts("");
}
return 0;
}
棋盤最大 26 格,DFS 狀態空間極小,瞬間出結果。