题目大意:问一个骑士能否不重复地踏遍整个棋盘。
思路:因为输出有一个坑爹的要求:Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. (lexicographically! 按字典序来进行优先输出),所以在走的过程就要按字典序地走。
AC program: #include<iostream> #include<stdio.h> #include<string.h> using namespace std; int a[8][2]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}}; int map[27][27], cnt,path[27*27][2],t,cse; int m,n; char num[27]={'#','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; int dfs(int p,int q) { //cout<<"pq "<<p<<' '<<q<<" cnt "<<cnt<<endl; map[p][q]=1;// 主要是为了标志第一层的 if(cnt==m*n)return 1; for(int k=0;k<8;k++)//注意不一定是26,是M if(p+a[k][0]>=1&&p+a[k][0]<=m&&q+a[k][1]>=1&&q+a[k][1]<=n&&!map[p+a[k][0]][q+a[k][1]]) { path[t][0]=p+a[k][0]; // path[t][1]=q+a[k][1]; ++t; ++cnt; map[p+a[k][0]][q+a[k][1]]=1; if(dfs(p+a[k][0],q+a[k][1]))return 1;// 这个return异常重要,对于DFS来说,因为它是返回的桥梁 map[p+a[k][0]][q+a[k][1]]=0;//其实这几步在return 0 上面做也可以的 --cnt; --t; } return 0;//这一步也很重要啊,是把无路可走的返回给dfs知道 } int main() { int test; scanf("%d",&test); cse=1; //注意是放在外面的 while(test--) { scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { memset(map,0,sizeof(map)); memset(path,0,sizeof(path));// cnt=1; t=0; path[t][0]=i; path[t][1]=j; //保存第几列的数字为了方便num数组输出 ++t; if( dfs(i,j)) { printf("Scenario #%d:\n",cse++); for(int p=0;p<t;p++) printf("%c%d",num[path[p][1]],path[p][0]);// printf("\n\n"); goto END; } } } printf("Scenario #%d:\nimpossible\n\n",cse++); // END:; } //system("pause"); return 0;}
看一个大牛的博客对解这道题应该会有不错的帮助,毕竟有图有真相
http://blog.csdn.net/lyy289065406/article/details/6647666