这题其实只有一点需要注意,就是国际象棋坐标系的选取。
国际象棋有个特点,标号的时候行为数字1~8,列为字母A~H,行从上到下为纵方向,列从左到右为横方向。不同于一般的坐标系,上个图就明白了:
剩下的就是普通的深搜了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 10;
const int INF = INT_MAX;
int p, q;
bool visit[MAXN][MAXN];
int direction[8][2] = {{-1, -2}, {1, -2}, {-2, -1}, {2, -1}, {-2, 1}, {2, 1}, {-1, 2}, {1, 2}};
bool dfs(int x, int y, int step, string path){
if(step == p*q){
cout << path << endl;
return true;
}
for(int i = 0; i < 8; i++){
int nx = x + direction[i][0];
int ny = y + direction[i][1];
if(visit[nx][ny] || nx >= p || nx < 0 || ny >= q || ny < 0) continue;
char col = ny + 'A';//列从A开始
char row = nx + '1';//行从1开始
visit[nx][ny] = true;
//cout << "........." + path + litter + number << endl;
if(dfs(nx, ny, step + 1, path + col + row)){
return true;//如果下面的路可以走,则直接返回当前递归,无须再搜索其他路径
}
visit[nx][ny] = false;
}
return false;//八个方向都不行,返回深搜失败
}
int main(){
// freopen("in.txt", "r", stdin);
int n;
while(~scanf("%d", &n)){
for(int i = 1; i <= n; i++){
scanf("%d %d", &p, &q);
memset(visit, false, sizeof(visit));
printf("Scenario #%d:\n", i);
visit[0][0] = true;
if(dfs(0, 0, 1, "A1")) ;
else if(!dfs(0, 0, 1, "A1")){
printf("impossible\n");
}
printf("\n");
}
}
return 0;
}