白騎士的移動(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的下一層節點中未曾入隊的節點全部入隊,並設置爲已入隊 
	} 
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章