题目来源:[NWPU][2014][TRN][4]搜索 G题
http://vjudge.net/contest/view.action?cid=49557#problem/G
作者:npufz
题目:给定一个指定宽高的棋盘,判断是否存在一条马能遍历棋盘的路径,马的出发点任意,结束点任意,如果存在,找出按字典序的那条,棋盘由H和W确定,H是行数,W为列 数,行的编号为1~H,列的编号为A到W对应的英文字母表第W个位置的字母
例如H=4,W=3 列为A,B,C;行为1,2,3,4;
路径为:A1B3C1A2B4C2A3B1C3A4B2C4
代码:
#include <iostream>
#include <cstdio>
using namespace std;
int cnt=1,num,w,h;
bool flag;
int vis[30][30];
int print()
{ int i1,j1,bs1=1;
printf("Scenario #%d:\n",cnt);
for( i1=0;i1<h;i1++)
for(j1=0;j1<w;j1++)
{
if(vis[i1][j1]==bs1)
{
printf("%c%d",j1+'A',i1+1);
bs1++;
while(bs1<=(w*h))
{
if(i1-1>=0&&j1-2>=0&&i1-1<h&&j1-2<w&&vis[i1-1][j1-2]==bs1)
{
i1-=1;j1-=2;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1+1>=0&&j1-2>=0&&i1+1<h&&j1-2<w&&vis[i1+1][j1-2]==bs1)
{
i1+=1;j1-=2;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1-2>=0&&j1-1>=0&&i1-2<h&&j1-1<w&&vis[i1-2][j1-1]==bs1)
{
i1-=2;j1-=1;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1+2>=0&&j1-1>=0&&i1+2<h&&j1-1<w&&vis[i1+2][j1-1]==bs1)
{
i1+=2;j1-=1;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1-2>=0&&j1+1>=0&&i1-2<h&&j1+1<w&&vis[i1-2][j1+1]==bs1)
{
i1-=2;j1+=1;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1+2>=0&&j1+1>=0&&i1+2<h&&j1+1<w&&vis[i1+2][j1+1]==bs1)
{
i1+=2;j1+=1;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1-1>=0&&j1+2>=0&&i1-1<h&&j1+2<w&&vis[i1-1][j1+2]==bs1)
{
i1-=1;j1+=2;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
else if(i1+1>=0&&j1+2>=0&&i1+1<h&&j1+2<w&&vis[i1+1][j1+2]==bs1)
{
i1+=1;j1+=2;
printf("%c%d",j1+'A',i1+1);
bs1++;
}
}
printf("\n\n");
break;return 0;
}
}
return 0;
}
bool dfs(int h1,int w1,int bs )
{
if(h1>=0&&h1<h&&w1>=0&&w1<w&&vis[h1][w1]==0&&bs<=(w*h))
{ vis[h1][w1]=bs;
bs++;
if(bs>(w*h)) {print();flag=false;return true;}
dfs(h1-1,w1-2,bs);
dfs(h1+1,w1-2,bs);
dfs(h1-2,w1-1,bs);
dfs(h1+2,w1-1,bs);
dfs(h1-2,w1+1,bs);
dfs(h1+2,w1+1,bs);
dfs(h1-1,w1+2,bs);
dfs(h1+1,w1+2,bs);
vis[h1][w1]=0;
}
else return true;
}
int main()
{ int i,j ;
scanf("%d",&num);
for(cnt=1;cnt<=num;cnt++)
{
scanf("%d%d",&h,&w);
flag=true;
for(j=0;j<=(w/2+1)&&flag;j++)
for(i=0;i<=(h/2+1)&&flag;i++)
{
dfs(0,0,1);
for(i=0;i<30;i++)
for(j=0;j<30;j++)
vis[i][j]=0;
}
if(flag) printf("Scenario #%d:\nimpossible\n\n",cnt);
}
return 0;
}
反思:主要是对深搜的递归调用理解不够深刻,还有就是一开始对路径的记录不够合适,后来发现只需再次遍历走过的棋盘去找路径即可,就解决了问题