小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
#include
#include
#include
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<
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<
// }
int ans=BFS(x,y);
if(ans==0)cout<<"Checkmate";
else cout<<ans;
return 0;
}