Description
A friend of you is doingresearch on the Traveling Knight Problem (TKP) where you are to find theshortest closed tour of knight moves that visits each square of a given set ofn squares on a chessboard exactly once. He thinks that the most difficult partof the problem is determining the smallest number of knight moves between twogiven squares and that, once you have accomplished this, finding the tour wouldbe easy.
Of course you know that it is vice versa. So you offer him to write a programthat solves the "difficult" part.
Your job is to write a program that takes two squares a and b as input and thendetermines the number of knight moves on a shortest route from a to b.
Input
The input will contain one ormore test cases. Each test case consists of one line containing two squaresseparated by one space. A square is a string consisting of a letter (a-h)representing the column and a digit (1-8) representing the row on thechessboard.
Output
For each test case, print oneline saying "To get from xx to yy takes n knight moves.".
Sample Input
e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6
Sample Output
To get from e2 to e4 takes 2knight moves.
To get from a1 to b2 takes 4knight moves.
To get from b2 to c3 takes 2knight moves.
To get from a1 to h8 takes 6knight moves.
To get from a1 to h7 takes 5knight moves.
To get from h8 to a1 takes 6knight moves.
To get from b1 to c3 takes 1knight moves.
To get from f6 to f6 takes 0knight moves.
题目大意:在棋盘一个8*8的国际象棋棋盘上输入马的开始位置和结束位置,求移动的最小步数。
分析:最基本的BFS求最短路问题,大致思想是:起点相同,速度相同,终点相同,步长相同,则用的步数最少的一定是路程最短的。其搜索树是一层一层往下的,而不是DFS那样一路到底的,其优势是找到最短路后就可以不找了。用一个包含“点”这种数据类型的队列来实现,每次选取一个点,把这个点一步就能走到的点都加进队列,同时这个点出队列,再照样处理下一个出队的点。一直到某个点就是终点为止。同时需要一个VIS数组来记录这个点是否已访问,防止搜回去了。
#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
struct point
{
int x;
int y;
int dis;
};
queue<point> q;
point cur,cur2;
int dirx[8]={-2,-2,-1,-1,1,1,2,2},diry[8]={-1,1,-2,2,2,-2,1,-1},ans,x1,y1,x2,y2,vis[100][100]={0};
void bfs()
{
int i,xn,yn;
while(!q.empty())
{
cur=q.front();
q.pop();
xn=cur.x;
yn=cur.y;
if (xn==x2&&yn==y2)
{
ans=cur.dis+1;
}
else
{
for (i=0;i<=7;i++)
{
xn=xn+dirx[i];
yn=yn+diry[i];
if (xn>=1&&xn<=8&&yn>=1&&yn<=8&&vis[xn][yn]==0)
{
cur2.x=xn;
cur2.y=yn;
vis[xn][yn]=1;
cur2.dis=cur.dis+1;
q.push(cur2);
}
xn=xn-dirx[i];
yn=yn-diry[i];
}
}
}
}
int main()
{
char a[3],b[3];
while(scanf("%s%s",a,b)!=EOF)
{
ans=0;
memset(vis,0,sizeof(vis));
while (!q.empty())
{
q.pop();
}
if (a[0]=='a')
{
x1=1;
}
else if (a[0]=='b')
{
x1=2;
}
else if (a[0]=='c')
{
x1=3;
}
else if (a[0]=='d')
{
x1=4;
}
else if (a[0]=='e')
{
x1=5;
}
else if (a[0]=='f')
{
x1=6;
}
else if (a[0]=='g')
{
x1=7;
}
else if (a[0]=='h')
{
x1=8;
}
if (b[0]=='a')
{
x2=1;
}
else if (b[0]=='b')
{
x2=2;
}
else if (b[0]=='c')
{
x2=3;
}
else if (b[0]=='d')
{
x2=4;
}
else if (b[0]=='e')
{
x2=5;
}
else if (b[0]=='f')
{
x2=6;
}
else if (b[0]=='g')
{
x2=7;
}
else if (b[0]=='h')
{
x2=8;
}
y1=a[1]-48;
y2=b[1]-48;
cur.x=x1;
cur.y=y1;
cur.dis=0;
q.push(cur);
bfs();
printf("To get from %s to %s takes %d knight moves.\n",a,b,ans-1);
}
return 0;
}