看到题目第一反应是八数码问题,但是出题人很好的给出了这一句:
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.
字典序最小的序列
也就是给了深搜的顺序
DFS解得:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>
#include <stack>
using namespace std;
typedef struct{
int x,y;
}Node ;
int n,m;
stack <Node> ans;
int dir_x[]={-2,-2,-1,-1,1,1,2,2},//棋盘X方向和正常X方向一致向右
dir_y[]={-1,1,-2,2,-2,2,-1,1};//棋盘Y正方向向下,所以要反过来
int vis[30][30];
int dfs(int x,int y,int num){
if(x<=0||x>n||y<=0||y>m) return 0;
if(vis[x][y]) return 0;
num++;
vis[x][y]=1;
if(num==n*m){
Node temp;
temp.x=x;temp.y=y;
ans.push(temp);
return 1;
}
for(int i=0;i<8;i++){
if(dfs(dir_x[i]+x,dir_y[i]+y,num)){
Node temp;
temp.x=x;temp.y=y;
ans.push(temp);//用栈把序列存下来
return 1;
}
}
vis[x][y]=0;//一个方向上深搜失败后,要重新标记,释放用过的点
return 0;
}
int main()
{
int T;
cin>>T;
for(int asd=1;asd<=T;asd++){
memset(vis,0,sizeof(vis));
cin>>m>>n;
cout<<"Scenario #"<<asd<<":"<<endl;
if(dfs(1,1,0)){
while(!ans.empty()){
Node temp=ans.top();
ans.pop();
cout<<(char)(temp.x-1+'A')<<temp.y;
}
cout<<endl;
}else
cout<<"impossible"<<endl;
if(asd!=T)//别忘了组与组之间换行
cout<<endl;
}
}