POJ 2488 -- A Knight's Journey(骑士游历)
题意:
给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。
经典的“骑士游历”问题
输入:第一行,整数n,接下来是n行,每一行为p和q,p为行数,q为列数,p用1...p编号,q用A...Q编号
马的走法:每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格,最后再往外横走或竖走一格(即走"日"字)。可以越子,没有中国象棋中的"蹩马腿"限制。
解题思路:
dfs
#include<iostream>
#include<cstring>
using namespace std;
int r,c;///行r,列c const int dr[] = {-, ,-, ,-,,-,};
const int dc[] = {-,-,-,-, ,, ,};
bool chess[]['Z'+]; struct square{
int row;
char col;
}; bool inside(int x,int y)
{
return x>= && x<=r && y>='A' && y<='A'+c-;
} bool dfs(square *way,int i,int j,int step)
{
chess[i][j]=true;
way[step].row=i;
way[step].col=j;
if(step==r*c)
return true; for(int k=;k<;k++) //骑士从当前位置尝试跳到其他位置
{
int ii,jj;
ii = i+dr[k];jj = j+dc[k];
if(!chess[ii][jj] && inside(ii,jj))
if(dfs(way,ii,jj,step+))
return true;
} chess[i][j]=false; //能执行到这步,说明前面跳的8步都不符合要求
return false; //即当前位置是错误位置,擦除记录返回上一步
} int main()
{
int n;
cin>>n;
for(int i=;i<=n;i++)
{
cin>>r>>c;
bool flag = false;
memset(chess,false,sizeof(chess));
square *way = new square[r*c+];
for(int i='A';i<='A'+c-;i++)
{
for(int j=;j<=r;j++)
{
flag = dfs(way,j,i,);
if(flag)
break;
}
if(flag)
break;
} ///打印解
cout<<"Scenario #"<<i<<":"<<endl;
if(flag)
{
for(int k=;k<=r*c;k++)
cout<<way[k].col<<way[k].row;
cout<<endl<<endl;
}else{
cout<<"impossible"<<endl<<endl;
} }
return ;
}