POJ2488 A Knight's Journey(DFS)
题意:
输入一些棋盘对应的行和列,看骑士(日字)能不能走完整个棋盘,可以从任何地方开始,注意要字典序输出
要点:
虽然说骑士可以从棋盘上任意一点出发,但因为要按字典序(lexicographically)输出,所以当然从A1出发字典序最小,不用担心为什么任意一点变成A1也行,因为反正是可以走过整个棋盘,那么肯定经过A1,那么其实是连着的一个环,从哪一点出发都无所谓。而且还有对应的走的顺序是要固定的,也即是要照字典序小的先走,x要从小到大(-2到2),这个次序是特殊的,其他的就是普通的DFS。
15190196 | Seasonal | 2488 | Accepted | 172K | 16MS | C++ | 1009B | 2016-02-23 14:17:02 |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int visit[30][30];
int p, q;
char path[1050][2];
int d[8][2] = { {-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1} };//这里有特殊的顺序的,要尽量使字母小
bool flag;
void dfs(int x,int y,int count)
{
int i, j;
if (count == p*q)
{
for (int i = 0; i<count; i++)
printf("%c%d", path[i][0] + 'A', path[i][1] + 1);
printf("\n");
flag = true;
return;
}
for (i = 0; i < 8; i++)
{
int xx = x + d[i][0];
int yy = y + d[i][1];
if (xx >= 0 && xx < q&&yy >= 0 && yy < p&&!visit[xx][yy]&&!flag)
{
visit[xx][yy] = 1;
path[count][0] = xx;path[count][1] = yy;
dfs(xx, yy,count+1);
visit[xx][yy] = 0; //如果不成功要回退
}
}
}
int main()
{
int t;
scanf("%d", &t);
for (int k = 1; k <= t;k++)
{
flag = false;
scanf("%d%d", &p, &q);
memset(visit, 0, sizeof(visit));
visit[0][0] = 1;
path[0][0] = 0, path[0][1] = 0;//从A1开始一定字典序最小
printf("Scenario #%d:\n", k);
dfs(0, 0,1);
if (!flag)
printf("impossible\n");
printf("\n");
}
return 0;
}