题意:给出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; }