shuoj 1659 跳马问题

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;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值