大致题意:
给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。
经典的“骑士游历”问题,DFS水题一道
解题思路:
难度不大,但要注意的地方有3点:
1、 题目要求以"lexicographically"方式输出,也就是字典序...要以字典序输出路径,那么搜索的方向(我的程序是path()函数)就要以特殊的顺序排列了...这样只要每次从dfs(A,1)开始搜索,第一个成功遍历的路径一定是以字典序排列...
下图是搜索的次序,马的位置为当前位置,序号格为测试下一步的位置的测试先后顺序
按这个顺序测试,那么第一次成功周游的顺序就是字典序
2、国际象棋的棋盘,行为数字p;列为字母q
#include<cstdio>
#include<cstring>
using namespace std;
int n,m, arr[8][2] = {{-1, -2}, {1, -2}, {-2, -1}, {2, -1}, {-2, 1}, {2, 1}, {-1, 2}, {1, 2}};
int visited[30][30], ax[30], ay[30], flag;
void DFS(int x, int y, int deep){
ax[deep] = x;ay[deep] = y;
if(deep == n * m){
flag = 1;
return;
}
for(int i = 0; i < 8; i++){
int tx = x + arr[i][0];
int ty = y + arr[i][1];
if(tx < 0 || ty < 0 || tx >= n || ty >=m || visited[tx][ty] || flag) continue;
visited[tx][ty] = 1;
DFS(tx, ty, deep + 1);
visited[tx][ty] = 0;
}
}
int main(){
int t;
while(scanf("%d", &t) != EOF){
for(int tcase = 1; tcase <= t; tcase++){
scanf("%d%d", &n, &m);
printf("Scenario #%d:\n", tcase);
if(n * m > 26){
printf("impossible\n");
continue;
}
memset(visited,0, sizeof(visited));
flag = 0;
visited[0][0] = 1;
DFS(0, 0, 1);
if(!flag){
printf("impossible\n");
}
else{
for(int i = 1; i <= n * m; i++){
printf("%c%d", 'A' + ay[i], ax[i] + 1);
}
printf("\n");
}
printf("\n");
}
}
return 0;
}