【题意简述】:骑士想要周游列国,现在这个国就是这个棋盘,(就是他要走遍棋盘的每一个角落)骑士只能向八个方向走“日”字,而且不能重复,现在如果可以做到,就按 字典序 输出骑士走的路径,如果不可以就输出 “impossible”!(我错了好多次,就是因为打错了这个英文)
【思路】:看到这种在棋盘上走的,就知道是有关搜索的题目,然后要求不能重复,所以一定要回溯!最重要的就是这个字典序,只要够清楚这个字典序,其他应该不是问题最后就变成了这个代码,深搜+回溯!
很不错的一道DFS!!
// 256K 16Ms
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 30;
int vis[maxn][maxn];
int n,m;
//八个方向,也是字典序的必要顺序!!思考为什么是这个顺序??
int dir[8][2] = {-2, -1, -2, 1, -1, -2, -1, 2,1, -2, 1, 2, 2, -1,2, 1};
struct Path
{
int x,y;
}p[maxn];
int flag;
void dfs(int x,int y,int step)
{
if(flag) return;
p[step].x= x;
p[step].y= y;
if(step == m*n)
{
flag = 1;
return;
}
Path next;
for(int i=0;i<8;i++)
{
next.x = x + dir[i][0];
next.y = y + dir[i][1];
if(next.x >= 1&&next.x<= n&&next.y>=1 && next.y <= m && !vis[next.x][next.y]){
vis[next.x][next.y] = 1;
dfs(next.x,next.y, step+1);
vis[next.x][next.y] = 0;
}
}
return;
}
int main()
{
int T;
cin>>T;
for(int t= 1;t<=T;t++)
{
cin>>m>>n; // 先输入列再输入行!!
memset(vis,0,sizeof(vis));
memset(p,0,sizeof(p));
flag = 0;
vis[1][1] = 1;
dfs(1,1,1); //这三个参数分别是,x,y和step,代表所走的方向和要走几步!!
cout<<"Scenario #"<<t<<":"<<endl;
if(flag)
{
for(int i=1;i<=n*m;i++)
cout<<char(p[i].x-1+'A')<<p[i].y;
cout<<endl;
}
else cout<<"impossible"<<endl;
if(t!=T) cout<<endl;
}
return 0;
}