小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,第一次找到的就是最短次数,用dfs剪枝了还会超时
#include <iostream> //7-68 白骑士的移动 (30分)
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
string str[8];
bool vis[9][9];
int jump[8][2] = {{2, 1}, {2, -1}, {1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {-2, -1}, {-2, 1}};
int jump1[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int jump2[4][2] = {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}};
int a1, b1; //终点
int ans = 100;
struct node{
int x, y, k;
};
bool RightPlace(int x, int y)
{
if (x >= 0 && x < 8)
if (y >= 0 && y < 8)
return true;
return false;
}
void MarkR(int x, int y) //战车
{
vis[x][y] = true;
for (int i = 0; i < 4; i++)
for (int j = 1; j < 8; j++)
{
int xt = x + j * jump1[i][0];
int yt = y + j * jump1[i][1];
if(RightPlace(xt, yt))
{
if(str[xt][yt] == '.')
vis[xt][yt] = true;
else
break;
}
}
}
void MarkB(int x, int y) //主教
{
vis[x][y] = true;
for (int i = 0; i < 4; i++)
for (int j = 1; j < 8; j++)
{
int xt = x + j * jump2[i][0];
int yt = y + j * jump2[i][1];
if(RightPlace(xt, yt))
{
if(str[xt][yt] == '.')
vis[xt][yt] = true;
else
break;
}
}
}
void dfs(int a, int b, int k) //dfs会超时<<<<
{
if(a == a1 && b == b1)
{
cout << k << endl;
ans = min(ans, k);
return;
}
for (int i = 0; i < 8; i++)
{
int x = a + jump[i][0];
int y = b + jump[i][1];
if(RightPlace(x, y) && !vis[x][y])
{
vis[x][y] = true;
if(k + 1 <= ans)
dfs(x, y, k + 1);
vis[x][y] = false;
}
}
}
int bfs(int a, int b)
{
queue<node> q;
q.push({a, b, 0});
while (!q.empty())
{
int x = q.front().x;
int y = q.front().y;
int k = q.front().k;
vis[x][y] = true;
q.pop();
if(x == a1 && y == b1)
return k;
for (int i = 0; i < 8; i++)
{
int xt = x + jump[i][0];
int yt = y + jump[i][1];
if(RightPlace(xt, yt) && !vis[xt][yt])
q.push({xt, yt, k + 1});
}
}
return -1;
}
int main()
{
int a0, b0; //起点
for (int i = 0; i < 8; i++)
cin >> str[i];
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
if (str[i][j] == 'K')
a0 = i, b0 = j;
if(str[i][j] == 'Q')
a1 = i, b1 = j;
if(str[i][j] == 'R')
MarkR(i, j);
else if(str[i][j] == 'B')
MarkB(i, j);
}
// vis[a0][b0] = true;
// dfs(a0, b0, 0);
// if(ans == 100)
// cout << "Checkmate" << endl;
// else
// cout << ans << endl;
int t = bfs(a0, b0);
if(t > 0)
cout << t << endl;
else
cout << "Checkmate" << endl;
system("pause");
return 0;
}