http://poj.org/problem?id=2488
(1) 注意输入 n,m 顺序,不能弄反了(好几次没注意)。
(2) 搜索深度为n*m 或还是n*m-1 要注意判断。
(3)打印路径关键是明确数组 after[30][30][2] 的确切含义,本质是记录一组 x, y 对应的下一组 x, y,并不复杂。但是不理解本质时,代码死活都是看不懂的。
(4)初始化注意字典序问题:
int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};
具体代码:


#include<stdio.h> #include<string.h> int n, m, flag; int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1}; int map[30][30]; int after[30][30][2], xx, yy; void dfs(int px, int py, int depth) { int i, j, k; if(flag) return ; if(depth==n*m) { flag=1; return ; } for(i=0;i<8;i++) { int tx, ty; tx=px+dir[i][0]; ty=py+dir[i][1]; if(tx<=0||tx>n||ty<=0||ty>m||map[tx][ty]) continue; map[tx][ty]=1; after[px][py][0]=tx; after[px][py][1]=ty; dfs(tx, ty, depth+1); if(flag) return ; map[tx][ty]=0; after[px][py][0]=-1; after[px][py][1]=-1; } } int main() { int i, j, k, t, cas=0;; while(scanf("%d", &t)!=EOF) { while(t--) { scanf("%d%d", &m, &n); flag=0; memset(after, -1, sizeof(after)); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { memset(map, 0, sizeof(map)); map[i][j]=1; xx=i;yy=j; dfs(i, j, 1); if(flag) break; } if(flag) break; } printf("Scenario #%d:\n", ++cas); if(flag) { printf("%c%d", xx+'A'-1, yy); int tx, ty, ex, ey; tx=after[xx][yy][0]; ty=after[xx][yy][1]; while(tx!=-1) { printf("%c%d", tx+'A'-1, ty); ex=after[tx][ty][0]; ey=after[tx][ty][1]; tx=ex, ty=ey; } printf("\n"); } else printf("impossible\n"); if(t) printf("\n"); } } return 0; }
其实记录、读取路径可以稍微简化:


#include<stdio.h> #include<string.h> int n, m, flag; int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1}; int map[30][30]; int after[30][30][2], xx, yy; void dfs(int px, int py, int depth) { int i, j, k; if(flag) return ; if(depth==n*m) { flag=1; return ; } for(i=0;i<8;i++) { int tx, ty; tx=px+dir[i][0]; ty=py+dir[i][1]; if(tx<=0||tx>n||ty<=0||ty>m||map[tx][ty]) continue; map[tx][ty]=1; after[px][py][0]=tx; after[px][py][1]=ty; dfs(tx, ty, depth+1); if(flag) return ; map[tx][ty]=0; after[px][py][0]=-1; after[px][py][1]=-1; } } int main() { int i, j, k, t, cas=0;; while(scanf("%d", &t)!=EOF) { while(t--) { scanf("%d%d", &m, &n); flag=0; memset(after, -1, sizeof(after)); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { memset(map, 0, sizeof(map)); map[i][j]=1; xx=i;yy=j; dfs(i, j, 1); if(flag) break; } if(flag) break; } printf("Scenario #%d:\n", ++cas); if(flag) { printf("%c%d", xx+'A'-1, yy); int tx, ty, ex, ey; tx=after[xx][yy][0]; ty=after[xx][yy][1]; while(tx!=-1) { printf("%c%d", tx+'A'-1, ty); ex=after[tx][ty][0]; ey=after[tx][ty][1]; tx=ex, ty=ey; } printf("\n"); } else printf("impossible\n"); if(t) printf("\n"); } } return 0; }