p×q 棋盤 (1 ≤ p×q ≤ 26),騎士從任意格出發,走「日」字步法,尋找訪問**所有格恰好一次**的路徑(騎士周遊)。多解時輸出**字典序最小**路徑(格子命名:列字母 A.. + 行號 1..)。無解輸出 impossible。
A1(字典序最小路徑必從最小格開始)。(-1,-2), (1,-2), (-2,-1), (2,-1), (-2,1), (2,1), (-1,2), (1,2) 對應 A1 字典序從小到大。p*q 即找到解,直接返回(保證字典序最小)。≤26),無需 Warnsdorff 启發式剪枝即可 AC。#include <bits/stdc++.h>
using namespace std;
int p, q, tot;
bool vis[27][27];
int path_x[30], path_y[30], len;
bool found;
const int dir[8][2] = {{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
void dfs(int x, int y) {
if (found) return;
if (len == tot) {
found = true;
for (int i=0;i=1 && nx<=p && ny>=1 && ny<=q && !vis[nx][ny]) {
vis[nx][ny] = true;
path_x[len] = nx; path_y[len] = ny; len++;
dfs(nx, ny);
vis[nx][ny] = false; len--;
}
}
}
int main() {
int T; scanf("%d", &T);
for (int cas=1; cas<=T; ++cas) {
scanf("%d%d", &p, &q);
tot = p*q;
memset(vis, 0, sizeof(vis));
found = false; len = 0;
vis[1][1] = true; path_x[0]=1; path_y[0]=1; len=1;
printf("Scenario #%d:\n", cas);
dfs(1, 1);
if (!found) printf("impossible");
puts("\n");
}
return 0;
}
Scenario #i: 後接路徑或 impossible,每組間空行。