题意:给出p*q大小的棋盘,要求不重复的让骑士遍历整个棋盘,并以字典序输出经过的棋盘的位置。
以数字为行(横坐标),字母为列(纵坐标),输出时是先输出行再输出列(即先输出横坐标在输 出纵坐标)。
因为要求字典序输出,只需方向数组按一定的顺序排列进行遍历,则最后骑士经过棋盘的顺序就是字典序的。
#include <iostream>
using namespace std;
const int size = 27;
bool map[size][size];
int dir[8][2] = {{-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}, {2, -1}, {2, 1}};//方向数组中元素的排列顺序不能改变
int step, p, q, ansx[size], ansy[size];
bool flag;
void dfs(int x, int y)
{
step++;
ansx[step] = x;
ansy[step] = y;
map[x][y] = true;
if(step == p*q)
{
flag = true;
return;
}
int tmpx, tmpy, i;
for(i = 0; i < 8; i++)
{
tmpx = x + dir[i][0];
tmpy = y + dir[i][1];
if(tmpx >= 1 && tmpx <= q && tmpy >= 1 && tmpy <= p && !map[tmpx][tmpy])//判断是否超过棋盘了
{
dfs(tmpx, tmpy);
if(flag) return;//当遍历棋盘之后,就可以直接返回,不用回溯了。
step--;//回溯
map[tmpx][tmpy] = false;
}
}
}
int main()
{
int cas;
int i, k;
scanf("%d", &cas);
for(k = 1; k <= cas; k++)
{
scanf("%d%d", &p, &q);
memset(map, false, sizeof(map));
step = 0; flag = false;
dfs(1, 1);
printf("Scenario #%d:\n", k);
if(flag)
{
for(i = 1; i <= p*q; i++)
{
printf("%c%d", ansx[i]+64, ansy[i]);//纵坐标输出是字母
}
printf("\n");
}
else printf("impossible\n");
if(k != cas) printf("\n");
}
return 0;
}