PTA白騎士的移動 (20分)

白騎士的移動(20分)

小S第一次接觸國際象棋。他發現國際象棋中的Knight棋子的移動方式和中國象棋中的馬類似,移動方式如圖所示。
在這裏插入圖片描述
於是小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

個人見解:此題爲經典的騎士移動問題,BFS(廣度優先搜索)來解決足以。只需要注意將棋盤加一些附加條件(有的格子是不能走的)。
AC代碼:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<queue>
using namespace std;
struct node{
	int x;
	int y;
	int bushu;//記錄步數
};
char qipan[8][8];
bool vis[8][8]={false};
int a[8][2] = {-2,-1, -2,1, 2,-1, 2,1, -1,-2, -1,2, 1,-2, 1,2};
void changeR(int x,int y){//遇到黑戰車的棋盤變化
	for(int i=0;i<8;i++){
		if(qipan[i][y]=='.'||i==x||qipan[i][y]=='-')qipan[i][y]='-';
		else break;
	}
}
void changeB(int x,int y){//遇到黑主教的棋盤變化,四個for循環有點麻煩了
	qipan[x][y]='-';
	int i,j;
	for(i=x+1,j=y+1;i<8,j<8;i++,j++){
		if(qipan[i][j]=='.'||qipan[i][j]=='-') qipan[i][j]='-';
		else break;
	} 
	for(i=x-1,j=y-1;i>=0,j>=0;i--,j--){
		if(qipan[i][j]=='.'||qipan[i][j]=='-') qipan[i][j]='-';
		else break;
	} 
	for(i=x+1,j=y-1;i<8,j>=0;i++,j--){
		if(qipan[i][j]=='.'||qipan[i][j]=='-') qipan[i][j]='-';
		else break;
	}
	for(i=x-1,j=y+1;i>=0,j<8;i--,j++){
		if(qipan[i][j]=='.'||qipan[i][j]=='-') qipan[i][j]='-';
		else break;
	}
}
bool pan(int x,int y){//用於判斷該格子是否可走
	if(x>=0&&y>=0&&x<8&&y<8&&vis[x][y]==false&&qipan[x][y]!='-') return true;
	else return false;
}
int BFS(int x,int y){//廣搜就ok
	vis[x][y]=true;
	node ans;
	ans.x=x;
	ans.y=y;
	ans.bushu=0;
	queue<node> q;
	q.push(ans);
	while(!q.empty()){
		node temp=q.front();
		q.pop();
		for(int i=0;i<8;i++){
			ans.x=temp.x+a[i][0];
			ans.y=temp.y+a[i][1];
			ans.bushu=temp.bushu+1;
			if(pan(ans.x,ans.y)){
				if(qipan[ans.x][ans.y]=='.'){
					vis[ans.x][ans.y]=true;
					q.push(ans);
				}
				else if(qipan[ans.x][ans.y]=='Q'){
//					cout<<ans.x<<" "<<ans.y<<endl;//debug用
					return ans.bushu;
				}
			}
		}
	}
	return 0;
}
int main(void){
	int x,y;
	for(int i=0;i<8;i++){
		for(int j=0;j<8;j++){
			scanf("%c",&qipan[i][j]);
			if(qipan[i][j]=='K'){
				x=i;y=j;	
			}
		}
		getchar();
	}
	for(int i=0;i<8;i++){
		for(int j=0;j<8;j++){
			if(qipan[i][j]=='R'){
				changeR(i,j);	
			}
			else if(qipan[i][j]=='B'){
				changeB(i,j);
			}
		}
	}
	//打印一下棋盤,debug用  - -。
//	for(int i=0;i<8;i++){
//		for(int j=0;j<8;j++){
//			printf("%c ",qipan[i][j]);
//		}
//		cout<<endl;
//	}
	int ans=BFS(x,y);
	if(ans==0)cout<<"Checkmate";
	else cout<<ans;
	return 0;
}
發佈了7 篇原創文章 · 獲贊 16 · 訪問量 751
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章