骑士移动

原题地址:http://forioi.com/p/1397

贝茜和表妹各有一颗棋子。棋子每次移一步,且棋子只能往如图所示的八个方向移动。比赛的规则很简单,两个人需要从起点将棋子移到终点,谁能花最少的步数从起点走到终点,就是赢家。为了确保能赢表妹,贝茜希望每次都能算出最少的步数,你能帮助她么,棋盘大小为8*8的。

输入

输入起点和终点,用一个空格隔开。(确保起点一定能走到终点)

输出

输入最少的步数。

样例

输入

a1 b2

输出

4

思路:这道题比较难,需要先把开始点和结束点标记为2,因为没障碍,其它标记为1,剩下来就交给bfs了。。。。

CODE:

#include<bits/stdc++.h>
using namespace std;
int ch1,sh1,ch2,sh2,zx[8]= {2,2,1,-1,-2,-2,-1,1},zy[8]= {-1,1,2,2,1,-1,-2,-2},sum[113][113],p[10][10],dx,dy,h[1013][3],ans;
char a,b,c,d;
int bfs(int x,int y) {
	int head=1,tail=1;
	p[x][y]=0;
	h[1][1]=x,h[1][2]=y;
	while(head<=tail) {
		for(int i=0; i<=7; i++) {
			dx=h[head][1]+zx[i];
			dy=h[head][2]+zy[i];
			if(dx<1||dx>8||dy<1||dy>8)//超过范围
				continue;
			if(p[dx][dy]) {
				h[++tail][1]=dx,h[tail][2]=dy;
				sum[dx][dy]=sum[h[head][1]][h[head][2]]+1;//多走一步
				if(p[dx][dy]==2)
					return sum[dx][dy];//返回步数
				p[dx][dy]=0;
			}
		}
		head++;
	}
	return 0;
}
int main() {
	while(cin>>a>>b>>c>>d) {
		memset(sum,0,sizeof(sum));
		memset(p,0,sizeof(p));
		memset(h,0,sizeof(h));
		ch1=(int)(a-'a'+1);//转坐标
		sh1=(int)(b-'1'+1);
		ch2=(int)(c-'a'+1);
		sh2=(int)(d-'1'+1);
		if(ch1==ch2&&sh1==sh2) {//如果起点等于终点
			cout<<0<<endl;
			continue;
		}
		for(int i=1; i<=8; i++)
			for(int j=1; j<=8; j++)
				if((i==ch1&&j==sh1)||(i==ch2&&j==sh2))//特殊标记
					p[i][j]=2;
				else
					p[i][j]=1;
		cout<<bfs(ch1,sh1)<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_55599629/article/details/120112325