POJ 2488 -- A Knight's Journey(骑士游历)
题意:
给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。
经典的“骑士游历”问题
输入:第一行,整数n,接下来是n行,每一行为p和q,p为行数,q为列数,p用1...p编号,q用A...Q编号
马的走法:每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外横走或竖走一格(即走"日"字)。可以越子,没有中国象棋中的"蹩马腿"限制。
解题思路:
dfs
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int r,c;///行r,列c 5 6 const int dr[] = {-1, 1,-2, 2,-2,2,-1,1}; 7 const int dc[] = {-2,-2,-1,-1, 1,1, 2,2}; 8 bool chess[27]['Z'+1]; 9 10 struct square{ 11 int row; 12 char col; 13 }; 14 15 bool inside(int x,int y) 16 { 17 return x>=1 && x<=r && y>='A' && y<='A'+c-1; 18 } 19 20 bool dfs(square *way,int i,int j,int step) 21 { 22 chess[i][j]=true; 23 way[step].row=i; 24 way[step].col=j; 25 if(step==r*c) 26 return true; 27 28 for(int k=0;k<8;k++) //骑士从当前位置尝试跳到其他位置 29 { 30 int ii,jj; 31 ii = i+dr[k];jj = j+dc[k]; 32 if(!chess[ii][jj] && inside(ii,jj)) 33 if(dfs(way,ii,jj,step+1)) 34 return true; 35 } 36 37 chess[i][j]=false; //能执行到这步,说明前面跳的8步都不符合要求 38 return false; //即当前位置是错误位置,擦除记录返回上一步 39 } 40 41 int main() 42 { 43 int n; 44 cin>>n; 45 for(int i=1;i<=n;i++) 46 { 47 cin>>r>>c; 48 bool flag = false; 49 memset(chess,false,sizeof(chess)); 50 square *way = new square[r*c+1]; 51 for(int i='A';i<='A'+c-1;i++) 52 { 53 for(int j=1;j<=r;j++) 54 { 55 flag = dfs(way,j,i,1); 56 if(flag) 57 break; 58 } 59 if(flag) 60 break; 61 } 62 63 ///打印解 64 cout<<"Scenario #"<<i<<":"<<endl; 65 if(flag) 66 { 67 for(int k=1;k<=r*c;k++) 68 cout<<way[k].col<<way[k].row; 69 cout<<endl<<endl; 70 }else{ 71 cout<<"impossible"<<endl<<endl; 72 } 73 74 } 75 return 0; 76 }