白骑士的移动(BFS)

目录

白骑士的移动

广搜(BFS)的伪代码 


白骑士的移动

小S第一次接触国际象棋。他发现国际象棋中的Knight棋子的移动方式和中国象棋中的马类似,移动方式如图所示。 QQ图片20191115182554.png

于是小S在棋盘上随意摆上了一些棋子,其中包括一枚白骑士、一枚黑皇后、若干黑战车和若干黑主教。

小S想知道,如何能在避开黑战车和黑主教的攻击范围的前提下,花费更少的步数吃掉黑皇后。

注1:战车的攻击范围呈直线,和中国象棋的車类似;主教的攻击范围呈斜线,无障碍物情况下可无限延伸。

注2:白骑士只能吃黑皇后,不可以吃掉黑战车和黑主教。

输入格式:

输入仅包含一组样例。

一组样例包含8行(分别对应1-8行),每行包含8个字符,每个字符代表对应行对应列的棋盘格子状况。

其中' . '代表格子上没有摆放任何棋子;' K '代表格子上摆放的是白骑士; ' Q '代表格子上摆放的是黑皇后; ' R '代表格子上摆放的是黑战车; ' B '代表格子上摆放的是黑主教。

注:题目保证白骑士的初始位置不在黑战车和黑主教的攻击范围内。

输出格式:

如果白骑士可以在避开黑战车和黑主教的攻击的情况下吃掉黑皇后,则输出花费步数的最小值;否则输出"Checkmate"。

输入样例1:

R.B.QB.R
........
........
........
........
........
........
.K......

输出样例1:

4

输入样例2:

....RR.Q
........
.K......
........
........
........
........
........

输出样例2:

Checkmate

 注意点:要注意初始化时,黑战车和黑主教的攻击范围,当遇到棋子时,这个棋子后面就无法攻击到了

还有黑主教是如何斜着攻击的,横坐标和纵坐标同时加或同时减,或者一个加,一个减,遇到棋子时停止即可

整体用的是广度优先遍历的思想来求解

ac代码:

#include<iostream>
#include<queue>
using namespace std;
char a[10][10]; //存放棋盘 
int v[10][10]={0};	//标记是否入过队列 
int ZL[8][2] = {-2,-1, -2,1, 2,-1, 2,1, -1,-2, -1,2, 1,-2,1,2}; //增量 

struct node{	 
	int x,y,step; 
}s,t;

int bfs(int x1,int y1){
	queue<node> q;
	s.x = x1;
	s.y = y1;
	s.step = 0;
	q.push(s);
	v[x1][y1] = 1;
	while(!q.empty()){
		t = q.front();
		q.pop();
		s.step = t.step +1;
		for(int i=0;i<8;i++){
			s.x = t.x + ZL[i][0];
			s.y = t.y + ZL[i][1];
			if(s.x>=0 && s.y>=0  && s.x<8  && s.y<8 && !v[s.x][s.y]){
				if(a[s.x][s.y]=='.'){
					v[s.x][s.y] = 1;
					q.push(s);
				}else if(a[s.x][s.y] == 'Q'){
					return s.step;
				}
			}
		}
	}
	return 0;
}
int main()
{
	int k,x1,y1;
	int x,y,x2,y2;
	for(int i=0;i<8;i++){
		scanf("%s",a[i]);
	}
	for(int i=0;i<8;i++){  //初始化 
		for(int j=0;j<8;j++){
			if(a[i][j]=='R'){ //黑战车 
				for(k=i+1;k<8;k++){
					if(a[k][j]=='.')
						a[k][j]='a';
					else break; //遇到人时停 
				} 
				for(k=i-1;k>=0;k--){
					if(a[k][j]=='.')
						a[k][j]='a'; 
					else break;
				} 
				for(k=j+1;k<8;k++){
					if(a[i][k]=='.')
						a[i][k]='a';
					else break;
				} 
				for(k=j-1;k>=0;k--){
					if(a[i][k]=='.')
						a[i][k]='a';
					else break;
				} 
			}else if(a[i][j]=='B'){ //黑主教 
				for(x=i+1,y=j+1;x<8,y<8;x++,y++){
					if(a[x][y]=='.')
						a[x][y]='a';
					else break; //遇到人时停
				} 
				for(x=i-1,y=j-1;x>=0,y>=0;x--,y--){
					if(a[x][y]=='.')
						a[x][y]='a';
					else break;
				} 
				for(x=i+1,y=j-1;x<8,y>=0;x++,y--){
					if(a[x][y]=='.')
						a[x][y]='a';
					else break;
				} 
				for(x=i-1,y=j+1;x>=0,y<8;x--,y++){
					if(a[x][y]=='.')
						a[x][y]='a';
					else break;
				} 
			}
			else if(a[i][j]=='K'){ //记录白骑士的下表 
				x1=i;y1=j;
			}
		}
	}
	int t=bfs(x1,y1);
	if(t)  printf("%d",t);
	else   printf("Checkmate");
	return 0;
}

广搜(BFS)的伪代码 

void BFS(int s){
	
	queue<int> q;
	q.push(s);
	
	while(!q.empty()){
		取出队首元素
		访问队首元素
		将队首元素出队
		将top的下一层节点中未曾入队的节点全部入队,并设置为已入队 
	} 
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值