Description
给定8*8方格棋盘,求棋盘上一只马从一个位置到达另一位置的最短路径长。
注意马是走“日”形的。
Input
输入有若干测试数据。
每组测试数据仅1行,每行上有2个方格pos1、pos2,之间用一个空格隔开,每格方格表示棋盘上的一个位置,该位置由表示列的1个字母(a-h)及表示行的一个数字(1-8)构成,如“d7”表示第4列第7行。
Output
对输入中每行上的2个方格pos1、pos2,输出马从位置pos1跳到pos2所需的最短路径长。如“a1==>a2: 3 moves”表示从位置a1跳到a2所需的最少步数是3。
注意:按输出样例所示格式输出,如“a1==>a2: 3 moves”中冒号后有一个空格,再跟着所需的最少步数。
Sample Input
a1 a2
a1 a3
a1 h8
g2 b8
Sample Output
a1==>a2: 3 moves
a1==>a3: 2 moves
a1==>h8: 6 moves
g2==>b8: 5 moves
分析:
本题和hdu1372的Knight Moves基本是如出一辙。用bfs可以完成。
马走日,分别向八个方向合法的坐标入列。同时记录层数来表示走过的步数(一步之内的所有情况均为同一层)。若是用结构体的话需要两个变量,现态的变量处理,入列次态的另一个变量。用pair也可以实现。
以下代码:
#include<bits/stdc++.h>
#define MP(a,b) make_pair(a,b)
using namespace std;
typedef pair<pair<int,int>,int> PIII; //分别用x,y,step来表示当前点的坐标和走过的步数
int a[8][8],sx,sy,tx,ty; //存图和始末坐标
bool vis[8][8]; //用来标记访问过的坐标
int dir[8][2]={{-2,-1},{2,-1},{-2,1},{2,1},{-1,-2},{-1,2},{1,-2},{1,2}}; //八个方向的走法
inline bool ok(int x,int y){ //判断坐标是否合法
if(x<8 && x>=0 && y<8 && y>=0)
return 1;
return 0;
}
int bfs(){
int ans=0,x,y,step;
queue<PIII>q;
q.push(MP(MP(sx,sy),0));
vis[sx][sy]=1;
while(!q.empty()){
PIII p=q.front();
q.pop();
x=p.first.first,y=p.first.second,step=p.second;
if(x==tx && y==ty) break;
for(int i=0;i<8;i++){
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(ok(dx,dy)&&vis[dx][dy]==0){
vis[dx][dy]=1;
q.push(MP(MP(dx,dy),step+1)); //下一个可以走的点入列,步数加1
}
}
}
return step;
}
int main(int argc, char** argv) {
char ch1,ch2;int w1,w2;
while(cin>>ch1>>w1){
getchar();
cin>>ch2>>w2;
memset(vis,0,sizeof(vis));
sx=ch1-'a';
sy=w1-1;
tx=ch2-'a';
ty=w2-1;
cout<<ch1<<w1<<"==>"<<ch2<<w2<<": "<<bfs()<<" moves"<<endl;
}
return 0;
}