骑士之旅
今天一时兴起,竟然在校运动会期间刷了一天的题,但由于太水,一整天都没有什么大的进展。看到POJ上的这道,似曾相识但又踌躇不已。英文翻译都让我痛苦不已。最后的翻译意思总结如下:
一个棋盘横坐标依次为ABCD....,纵坐标依次为1234....,一个骑士从棋盘的左上角(A1)开始游历,行走方法为2*3或3*2的格子的对角线。即如图中所示,骑士可以行走图8个圆点中的任何一个位置。现在希望找到一种按照字典顺序行走,并且能够游历完棋盘上所有点并且不重复行走的方案。如果可以,输出该方案的各个点坐标,如果不行输出impossible.
题目的思路很简单,就是利用了DFS(深度优先搜索)和递归的算法,但值得注意的就是题目要求按字典顺序输出,所以这里应特别强调一下骑士的走法顺序。
int nx[8] = { -1, 1, -2, 2, -2, 2, -1, 1 };
int ny[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
int ny[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
代码实现:
#include <stdio.h>
#include<string.h>
const int N =27;
int n, m_x, m_y;
int nx[8] = { -1, 1, -2, 2, -2, 2, -1, 1 };
int ny[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
bool f[N][N];
struct node{
int x, y;
}path[N*N+1];
bool isover(int x,int y )//判断是否越界函数
{
if( x>=m_x || x<0 || y>=m_y || y< 0 )
return 1;
return 0;
}
bool dfs(int dip,int x,int y )//深度优先搜索
{
if(dip==n)
{
int j;
for(j=0;j<dip;j++ )
{
printf("%c%d",path[j].y+'A',path[j].x+1);
}
printf("\n");
return true;
}
int i;
for(i=0;i<8;i++ )
{
int tx,ty;
tx=x+nx[i];
ty=y+ny[i];
if(!isover(tx,ty) && !f[ty][tx])
{
f[ty][tx]=true;
path[dip].x=tx;
path[dip].y=ty;
if(dfs(dip+1,tx,ty))
return true;
f[ty][tx]=false;
}
}
return false;
}
int main()
{
int cn,cnt;
scanf("%d",&cn);
for(cnt=1;cnt<=cn;cnt++ )
{
scanf("%d %d",&m_x,&m_y );
n = m_x*m_y;
memset(f,0,sizeof f);
printf("Scenario #%d:\n",cnt);
f[0][0]=true;
path[0].y=0;
path[0].x=0;
if(!dfs(1,0,0))
printf("impossible\n");
printf("\n");
}
return 0;
}