P5380 [THUPC2019] 鸭棋 题解
一道大模拟题。
分析
做这道题之前,我们首先需要捋一捋思路。
对于每一个操作,我们需要做的就是下面几点:
- 判断是否可行
- 如可行,则移动棋子
- 判断是否移除了对方的棋子
- 判断是否形成了将军局面
- 判断是否结束了游戏
就下面五点。
可行性
首先我们分析一下有哪些情况会导致操作不可行:
- 游戏已经结束。
这个在所有操作之前进行一个判断即可。 - 移动的起止点不在棋盘内。
这个在移动之前判断即可。 - 开始移动的地方没有己方棋子。
同上。 - 移动的目的地已经有了己方棋子。
同上。 - 移动的方式不符合棋子的可达位置。
对于每一种棋子分类判断。 - (象、马、鸭)被绊住。
与上方情况一起判断。
所有的情况只有这六种。
将军与否
这个与上面判断目的地是否符合棋子的可达位置相似。
但是,我采用的是判断一个王是否能被棋子吃掉的方法,与大部分人的不太一样,注意坐标的不同。
(就这个让我调了好长时间)
游戏结束
一旦有一方的王被移除,那么游戏就结束了。
这个判断移除的棋子类型的时候就顺便判断了。
实现
下面是代码实现部分:
定义
我们将七种棋子用数字表示,红方为1-7,蓝方为11-17。
顺序就是按照题目给的顺序,从1到7分别是:王士象马车鸭兵。
初始化
我一开始以为棋盘长10宽9,就按照这样写了下去,结果反了,所以注意这里的坐标问题。
void initMap()
{
memset(base, 0, sizeof(base));
base[4][0] = 1;
base[4][9] = 11;
base[3][0] = base[5][0] = 2;
base[3][9] = base[5][9] = 12;
base[2][0] = base[6][0] = 3;
base[2][9] = base[6][9] = 13;
base[1][0] = base[7][0] = 4;
base[1][9] = base[7][9] = 14;
base[0][0] = base[8][0] = 5;
base[0][9] = base[8][9] = 15;
base[0][2] = base[8][2] = 6;
base[0][7] = base[8][7] = 16;
base[0][3] = base[2][3] = base[4][3] = base[6][3] = base[8][3] = 7;
base[0][6] = base[2][6] = base[4][6] = base[6][6] = base[8][6] = 17;
}
是否越过边界
棋盘长为9,。宽为10,坐标从 (0,0) 开始,到 (8,9) 结束。
void checkOut()
{
bool flag = false;
if (sx < 0)flag = true;
if (sx > 8)flag = true;
if (sy < 0)flag = true;
if (sy > 9)flag = true;
if (tx < 0)flag = true;
if (tx > 8)flag = true;
if (ty < 0)flag = true;
if (ty > 9)flag = true;
if (flag)
{
puts("Invalid command");
isInvalid = true;
}
}
(其实本来可以写紧凑些的)
移动
我们这里直接对棋子的类型进行分析。
首先,我们需要判断我们的起止点是否合法,即起始点有没有棋子、目的地有没有己方棋子什么的。
if (base[sx][sy] / 10 != side)
{
puts("Invalid command");
isInvalid = true;
return;
}
else if (base[sx][sy] == 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
else if (base[tx][ty] / 10 == side && base[tx][ty] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
(其实本来可以写紧凑些的)
然后就是对每一种棋子的类型分开讨论:
王
王的可达范围是与其相邻的四个格子:
[pic here]
判定方法比较简单:
if (type == 1)
{
if (abs(sx - tx) + abs(sy - ty) > 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
士
士的可达范围为其四角的格子:
[pic here]
判定方法也很简单:
else if (type == 2)
{
if (abs(sx - tx) != 1 || abs(sy - ty) != 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
象
象在没有被绊住的情况下可以到达其四角距其两格的格子:
[pic here]
这时候需要判定两种情况,一是目的地不合法,二是目的地合法,但被绊住不能动。
else if (type == 3)
{
if (abs(sx - tx) != 2 || abs(sy - ty) != 2)
{
puts("Invalid command");
isInvalid = true;
return;
}
if (base[(sx + tx) / 2][(sy + ty) / 2] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
车
车能在当前行和当前列中随意移动,直到遇到了一个棋子。
如果遇到的是敌方棋子,那就可以吃掉对方;
如果遇到的是己方棋子就会被判定不合法。
(这里就不放图了)
首先,因为我们有了起止点,我们就可以先判断车所要到的地方是否是己方棋子。如果是的话就直接判定不合法。
然后我们需要判定起止点是否在同一行或同一列上,否则就不合法。
最后,我们从起始点向目的地扫,看中间有没有棋子,任何一方的都算,因为车不能跨过棋子。
else if (type == 5)
{
if (sx != tx && sy != ty)
{
puts("Invalid command");
isInvalid = true;
return;
}
bool collide = false;
if (sx != tx)
{
int tmpx = min(sx, tx);
for (int i = tmpx + 1; i < max(sx, tx); i++)
{
if (base[i][sy] != 0)
{
collide = true;
break;
}
}
}
else if (sy != ty)
{
int tmpy = min(sy, ty);
for (int i = tmpy + 1; i < max(sy, ty); i++)
{
if (base[sx][i] != 0)
{
collide = true;
break;
}
}
}
if (collide)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
马
马可以到的位置是日字形的地方,同时还需要注意绊住的情况:
[pic here]
else if (type == 4)
{
if (!(abs(sx - tx) == 2 && abs(sy - ty) == 1) && !(abs(sx - tx) == 1 && abs(sy - ty) == 2))
{
puts("Invalid command");
isInvalid = true;
return;
}
if (abs(sx - tx) > abs(sy - ty))
{
if (base[sx + (tx - sx) / 2][sy] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (base[sx][sy + (ty - sy) / 2] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
}
鸭
鸭的判定是最麻烦的一步,因为其需要注意的地方比较多。(主要是绊脚的地方多)
鸭可以走到的地方如下图:
[pic here]
else if (type == 6)
{
if (!(abs(sx - tx) == 3 && abs(sy - ty) == 2) && !(abs(sx - tx) == 2 && abs(sy - ty) == 3))
{
puts("Invalid command");
isInvalid = true;
return;
}
int kx = (tx - sx > 0) ? 1 : -1;
int ky = (ty - sy > 0) ? 1 : -1;
if (abs(sx - tx) > abs(sy - ty))
{
if (base[sx + kx][sy] != 0 || base[sx + 2 * kx][sy + ky] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (base[sx][sy + ky] != 0 || base[sx + kx][sy + 2 * ky] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
}
兵
兵能走到的地方是与其八联通的格子:
[pic here]
else if (type == 7)
{
if (abs(sx - tx) > 1 || abs(sy - ty) > 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
判定是否将军
我们判断是否将军的函数其实与移动的函数差不多,但是我不会写(雾)
我这里用的是判断王能不能被攻击到的方法。
一个让我调了很长时间的一点就是,我这里还需要转化一下参考系,所以绊脚的位置不一样了。
bool checkMate(int k)
{
int x = 0, y = 0;
for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 9; j++)
if (base[i][j] == (k ^ 1) * 10 + 1)
{
x = i;
y = j;
break;
}
bool flag = false;
for (int i = x + 1; i <= 8; i++)
{
if (base[i][y] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[i][y] != 0)break;
}
for (int i = x - 1; i >= 0; i--)
{
if (base[i][y] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[i][y] != 0)break;
}
for (int i = y + 1; i <= 9; i++)
{
if (base[x][i] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[x][i] != 0)break;
}
for (int i = y - 1; i >= 0; i--)
{
if (base[x][i] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[x][i] != 0)break;
}
if (flag)return flag;
if (x <= 7 && base[x + 1][y] == k * 10 + 1)flag = true;
if (y <= 8 && base[x][y + 1] == k * 10 + 1)flag = true;
if (x >= 1 && base[x - 1][y] == k * 10 + 1)flag = true;
if (y >= 1 && base[x][y - 1] == k * 10 + 1)flag = true;
if (flag)return flag;
if (x <= 7 && y <= 8 && base[x + 1][y + 1] == k * 10 + 2)flag = true;
if (x >= 1 && y <= 8 && base[x - 1][y + 1] == k * 10 + 2)flag = true;
if (x <= 7 && y >= 1 && base[x + 1][y - 1] == k * 10 + 2)flag = true;
if (x >= 1 && y >= 1 && base[x - 1][y - 1] == k * 10 + 2)flag = true;
if (flag)return flag;
if (x <= 7 && y <= 8 && base[x + 1][y + 1] == k * 10 + 7)flag = true;
if (x >= 1 && y <= 8 && base[x - 1][y + 1] == k * 10 + 7)flag = true;
if (x <= 7 && y >= 1 && base[x + 1][y - 1] == k * 10 + 7)flag = true;
if (x >= 1 && y >= 1 && base[x - 1][y - 1] == k * 10 + 7)flag = true;
if (x <= 7 && base[x + 1][y] == k * 10 + 7)flag = true;
if (y <= 8 && base[x - 1][y] == k * 10 + 7)flag = true;
if (x >= 1 && base[x][y + 1] == k * 10 + 7)flag = true;
if (y >= 1 && base[x][y - 1] == k * 10 + 7)flag = true;
if (flag)return flag;
if (x <= 6 && y <= 8 && base[x + 2][y + 1] == k * 10 + 4 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 2 && y <= 8 && base[x - 2][y + 1] == k * 10 + 4 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 6 && y >= 1 && base[x + 2][y - 1] == k * 10 + 4 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 2 && y >= 1 && base[x - 2][y - 1] == k * 10 + 4 && base[x - 1][y - 1] == 0)flag = true;
if (x <= 7 && y <= 7 && base[x + 1][y + 2] == k * 10 + 4 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 1 && y <= 7 && base[x - 1][y + 2] == k * 10 + 4 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 7 && y >= 2 && base[x + 1][y - 2] == k * 10 + 4 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 1 && y >= 2 && base[x - 1][y - 2] == k * 10 + 4 && base[x - 1][y - 1] == 0)flag = true;
if (flag)return flag;
if (x <= 6 && y <= 7 && base[x + 2][y + 2] == k * 10 + 3 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 2 && y <= 7 && base[x - 2][y + 2] == k * 10 + 3 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 6 && y >= 2 && base[x + 2][y - 2] == k * 10 + 3 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 2 && y >= 2 && base[x - 2][y - 2] == k * 10 + 3 && base[x - 1][y - 1] == 0)flag = true;
if (flag)return flag;
if (x <= 5 && y <= 7 && base[x + 3][y + 2] == k * 10 + 6 && base[x + 1][y + 1] == 0 && base[x + 2][y + 2] == 0)flag = true;
if (x >= 3 && y <= 7 && base[x - 3][y + 2] == k * 10 + 6 && base[x - 1][y + 1] == 0 && base[x - 2][y + 2] == 0)flag = true;
if (x <= 5 && y >= 2 && base[x + 3][y - 2] == k * 10 + 6 && base[x + 1][y - 1] == 0 && base[x + 2][y - 2] == 0)flag = true;
if (x >= 3 && y >= 2 && base[x - 3][y - 2] == k * 10 + 6 && base[x - 1][y - 1] == 0 && base[x - 2][y - 2] == 0)flag = true;
if (x <= 6 && y <= 6 && base[x + 2][y + 3] == k * 10 + 6 && base[x + 1][y + 1] == 0 && base[x + 2][y + 2] == 0)flag = true;
if (x >= 2 && y <= 6 && base[x - 2][y + 3] == k * 10 + 6 && base[x - 1][y + 1] == 0 && base[x - 2][y + 2] == 0)flag = true;
if (x <= 6 && y >= 3 && base[x + 2][y - 3] == k * 10 + 6 && base[x + 1][y - 1] == 0 && base[x + 2][y - 2] == 0)flag = true;
if (x >= 2 && y >= 3 && base[x - 2][y - 3] == k * 10 + 6 && base[x - 1][y - 1] == 0 && base[x - 2][y - 2] == 0)flag = true;
return flag;
}
然后就没有大的操作了。
判断是否结束游戏就看被移除的棋子类型即可。
输出的时候直接switch case
就可以了。
全部加起来:
C++:
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int base[20][20];
bool isCaptured = false;
bool isInvalid = false;
bool isCheckmate = false;
int side = 0;
int sx, sy, tx, ty;
int knockOut = 0;
int cnt = 0;
void initMap()
{
memset(base, 0, sizeof(base));
base[4][0] = 1;
base[4][9] = 11;
base[3][0] = base[5][0] = 2;
base[3][9] = base[5][9] = 12;
base[2][0] = base[6][0] = 3;
base[2][9] = base[6][9] = 13;
base[1][0] = base[7][0] = 4;
base[1][9] = base[7][9] = 14;
base[0][0] = base[8][0] = 5;
base[0][9] = base[8][9] = 15;
base[0][2] = base[8][2] = 6;
base[0][7] = base[8][7] = 16;
base[0][3] = base[2][3] = base[4][3] = base[6][3] = base[8][3] = 7;
base[0][6] = base[2][6] = base[4][6] = base[6][6] = base[8][6] = 17;
}
void init()
{
isInvalid = false;
isCheckmate = false;
knockOut = 0;
}
void checkOut()
{
bool flag = false;
if (sx < 0)flag = true;
if (sx > 8)flag = true;
if (sx < 0)flag = true;
if (sy > 9)flag = true;
if (tx < 0)flag = true;
if (tx > 8)flag = true;
if (tx < 0)flag = true;
if (ty > 9)flag = true;
if (flag)
{
puts("Invalid command");
isInvalid = true;
}
}
void move()
{
if (base[sx][sy] / 10 != side)
{
puts("Invalid command");
isInvalid = true;
return;
}
else if (base[sx][sy] == 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
else if (base[tx][ty] / 10 == side && base[tx][ty] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
int type = base[sx][sy] % 10;
if (type == 1)
{
if (abs(sx - tx) + abs(sy - ty) > 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 2)
{
if (abs(sx - tx) != 1 || abs(sy - ty) != 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 3)
{
if (abs(sx - tx) != 2 || abs(sy - ty) != 2)
{
puts("Invalid command");
isInvalid = true;
return;
}
if (base[(sx + tx) / 2][(sy + ty) / 2] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 4)
{
if (!(abs(sx - tx) == 2 && abs(sy - ty) == 1) && !(abs(sx - tx) == 1 && abs(sy - ty) == 2))
{
puts("Invalid command");
isInvalid = true;
return;
}
if (abs(sx - tx) > abs(sy - ty))
{
if (base[sx + (tx - sx) / 2][sy] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (base[sx][sy + (ty - sy) / 2] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
}
else if (type == 5)
{
if (sx != tx && sy != ty)
{
puts("Invalid command");
isInvalid = true;
return;
}
bool collide = false;
if (sx != tx)
{
int tmpx = min(sx, tx);
for (int i = tmpx + 1; i < max(sx, tx); i++)
{
if (base[i][sy] != 0)
{
collide = true;
break;
}
}
}
else if (sy != ty)
{
int tmpy = min(sy, ty);
for (int i = tmpy + 1; i < max(sy, ty); i++)
{
if (base[sx][i] != 0)
{
collide = true;
break;
}
}
}
if (collide)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 6)
{
if (!(abs(sx - tx) == 3 && abs(sy - ty) == 2) && !(abs(sx - tx) == 2 && abs(sy - ty) == 3))
{
puts("Invalid command");
isInvalid = true;
return;
}
int kx = (tx - sx > 0) ? 1 : -1;
int ky = (ty - sy > 0) ? 1 : -1;
if (abs(sx - tx) > abs(sy - ty))
{
if (base[sx + kx][sy] != 0 || base[sx + 2 * kx][sy + ky] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (base[sx][sy + ky] != 0 || base[sx + kx][sy + 2 * ky] != 0)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
}
else if (type == 7)
{
if (abs(sx - tx) > 1 || abs(sy - ty) > 1)
{
puts("Invalid command");
isInvalid = true;
return;
}
}
knockOut = base[tx][ty];
base[tx][ty] = base[sx][sy];
base[sx][sy] = 0;
}
bool checkMate(int k)
{
int x = 0, y = 0;
for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 9; j++)
if (base[i][j] == (k ^ 1) * 10 + 1)
{
x = i;
y = j;
break;
}
bool flag = false;
for (int i = x + 1; i <= 8; i++)
{
if (base[i][y] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[i][y] != 0)break;
}
for (int i = x - 1; i >= 0; i--)
{
if (base[i][y] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[i][y] != 0)break;
}
for (int i = y + 1; i <= 9; i++)
{
if (base[x][i] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[x][i] != 0)break;
}
for (int i = y - 1; i >= 0; i--)
{
if (base[x][i] == k * 10 + 5)
{
flag = true;
break;
}
else if (base[x][i] != 0)break;
}
if (flag)return flag;
if (x <= 7 && base[x + 1][y] == k * 10 + 1)flag = true;
if (y <= 8 && base[x][y + 1] == k * 10 + 1)flag = true;
if (x >= 1 && base[x - 1][y] == k * 10 + 1)flag = true;
if (y >= 1 && base[x][y - 1] == k * 10 + 1)flag = true;
if (flag)return flag;
if (x <= 7 && y <= 8 && base[x + 1][y + 1] == k * 10 + 2)flag = true;
if (x >= 1 && y <= 8 && base[x - 1][y + 1] == k * 10 + 2)flag = true;
if (x <= 7 && y >= 1 && base[x + 1][y - 1] == k * 10 + 2)flag = true;
if (x >= 1 && y >= 1 && base[x - 1][y - 1] == k * 10 + 2)flag = true;
if (flag)return flag;
if (x <= 7 && y <= 8 && base[x + 1][y + 1] == k * 10 + 7)flag = true;
if (x >= 1 && y <= 8 && base[x - 1][y + 1] == k * 10 + 7)flag = true;
if (x <= 7 && y >= 1 && base[x + 1][y - 1] == k * 10 + 7)flag = true;
if (x >= 1 && y >= 1 && base[x - 1][y - 1] == k * 10 + 7)flag = true;
if (x <= 7 && base[x + 1][y] == k * 10 + 7)flag = true;
if (y <= 8 && base[x - 1][y] == k * 10 + 7)flag = true;
if (x >= 1 && base[x][y + 1] == k * 10 + 7)flag = true;
if (y >= 1 && base[x][y - 1] == k * 10 + 7)flag = true;
if (flag)return flag;
if (x <= 6 && y <= 8 && base[x + 2][y + 1] == k * 10 + 4 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 2 && y <= 8 && base[x - 2][y + 1] == k * 10 + 4 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 6 && y >= 1 && base[x + 2][y - 1] == k * 10 + 4 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 2 && y >= 1 && base[x - 2][y - 1] == k * 10 + 4 && base[x - 1][y - 1] == 0)flag = true;
if (x <= 7 && y <= 7 && base[x + 1][y + 2] == k * 10 + 4 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 1 && y <= 7 && base[x - 1][y + 2] == k * 10 + 4 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 7 && y >= 2 && base[x + 1][y - 2] == k * 10 + 4 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 1 && y >= 2 && base[x - 1][y - 2] == k * 10 + 4 && base[x - 1][y - 1] == 0)flag = true;
if (flag)return flag;
if (x <= 6 && y <= 7 && base[x + 2][y + 2] == k * 10 + 3 && base[x + 1][y + 1] == 0)flag = true;
if (x >= 2 && y <= 7 && base[x - 2][y + 2] == k * 10 + 3 && base[x - 1][y + 1] == 0)flag = true;
if (x <= 6 && y >= 2 && base[x + 2][y - 2] == k * 10 + 3 && base[x + 1][y - 1] == 0)flag = true;
if (x >= 2 && y >= 2 && base[x - 2][y - 2] == k * 10 + 3 && base[x - 1][y - 1] == 0)flag = true;
if (flag)return flag;
if (x <= 5 && y <= 7 && base[x + 3][y + 2] == k * 10 + 6 && base[x + 1][y + 1] == 0 && base[x + 2][y + 2] == 0)flag = true;
if (x >= 3 && y <= 7 && base[x - 3][y + 2] == k * 10 + 6 && base[x - 1][y + 1] == 0 && base[x - 2][y + 2] == 0)flag = true;
if (x <= 5 && y >= 2 && base[x + 3][y - 2] == k * 10 + 6 && base[x + 1][y - 1] == 0 && base[x + 2][y - 2] == 0)flag = true;
if (x >= 3 && y >= 2 && base[x - 3][y - 2] == k * 10 + 6 && base[x - 1][y - 1] == 0 && base[x - 2][y - 2] == 0)flag = true;
if (x <= 6 && y <= 6 && base[x + 2][y + 3] == k * 10 + 6 && base[x + 1][y + 1] == 0 && base[x + 2][y + 2] == 0)flag = true;
if (x >= 2 && y <= 6 && base[x - 2][y + 3] == k * 10 + 6 && base[x - 1][y + 1] == 0 && base[x - 2][y + 2] == 0)flag = true;
if (x <= 6 && y >= 3 && base[x + 2][y - 3] == k * 10 + 6 && base[x + 1][y - 1] == 0 && base[x + 2][y - 2] == 0)flag = true;
if (x >= 2 && y >= 3 && base[x - 2][y - 3] == k * 10 + 6 && base[x - 1][y - 1] == 0 && base[x - 2][y - 2] == 0)flag = true;
return flag;
}
void write()
{
switch (base[tx][ty])
{
case 1: { printf("red captain;"); break; }
case 2: { printf("red guard;"); break; }
case 3: { printf("red elephant;"); break; }
case 4: { printf("red horse;"); break; }
case 5: { printf("red car;"); break; }
case 6: { printf("red duck;"); break; }
case 7: { printf("red soldier;"); break; }
case 11: { printf("blue captain;"); break; }
case 12: { printf("blue guard;"); break; }
case 13: { printf("blue elephant;"); break; }
case 14: { printf("blue horse;"); break; }
case 15: { printf("blue car;"); break; }
case 16: { printf("blue duck;"); break; }
case 17: { printf("blue soldier;"); break; }
}
switch (knockOut)
{
case 0: { printf("NA;"); break; }
case 1: { printf("red captain;"); break; }
case 2: { printf("red guard;"); break; }
case 3: { printf("red elephant;"); break; }
case 4: { printf("red horse;"); break; }
case 5: { printf("red car;"); break; }
case 6: { printf("red duck;"); break; }
case 7: { printf("red soldier;"); break; }
case 11: { printf("blue captain;"); break; }
case 12: { printf("blue guard;"); break; }
case 13: { printf("blue elephant;"); break; }
case 14: { printf("blue horse;"); break; }
case 15: { printf("blue car;"); break; }
case 16: { printf("blue duck;"); break; }
case 17: { printf("blue soldier;"); break; }
}
if (knockOut == 1 || knockOut == 11)isCaptured = true;
if (!isCaptured && isCheckmate)printf("yes;");
else printf("no;");
if (isCaptured)printf("yes\n");
else printf("no\n");
}
int main()
{
initMap();
int Q;
scanf("%d", &Q);
for (int i = 1; i <= Q; i++)
{
init();
scanf("%d%d%d%d", &sy, &sx, &ty, &tx);
cnt++;
if (isCaptured)
{
puts("Invalid command");
continue;
}
checkOut();
move();
if (isInvalid)continue;
isCheckmate = checkMate(0) || checkMate(1);
write();
side ^= 1;
}
return 0;
}
C#:
using System;
namespace Main
{
class Map
{
public int[,] m = new int[20, 20];
public int side;
public bool isCaptured;
public bool isInvalid;
public bool isCheckmate;
public int knockOut;
public int sx, sy, tx, ty;
public Map()
{
Array.Clear(m, 0, m.Length);
side = 0;
isCaptured = false;
isInvalid = false;
isCheckmate = false;
knockOut = 0;
sx = 0; sy = 0; tx = 0; ty = 0;
}
public void Init()
{
m[4, 0] = 1;
m[4, 9] = 11;
m[3, 0] = m[5, 0] = 2;
m[3, 9] = m[5, 9] = 12;
m[2, 0] = m[6, 0] = 3;
m[2, 9] = m[6, 9] = 13;
m[1, 0] = m[7, 0] = 4;
m[1, 9] = m[7, 9] = 14;
m[0, 0] = m[8, 0] = 5;
m[0, 9] = m[8, 9] = 15;
m[0, 2] = m[8, 2] = 6;
m[0, 7] = m[8, 7] = 16;
m[0, 3] = m[2, 3] = m[4, 3] = m[6, 3] = m[8, 3] = 7;
m[0, 6] = m[2, 6] = m[4, 6] = m[6, 6] = m[8, 6] = 17;
}
public void Clear()
{
isInvalid = false;
isCheckmate = false;
knockOut = 0;
}
public void CheckOut()
{
bool flag = false;
if (sx < 0 || sx > 8) flag = true;
if (sy < 0 || sy > 9) flag = true;
if (tx < 0 || tx > 8) flag = true;
if (ty < 0 || ty > 9) flag = true;
if (flag)
{
Console.WriteLine("Invalid command");
isInvalid = true;
}
}
public void Move()
{
if (m[sx, sy] / 10 != side)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
else if (m[sx, sy] == 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
else if (m[tx, ty] / 10 == side && m[tx, ty] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
int type = m[sx, sy] % 10;
if (type == 1)
{
if (Math.Abs(sx - tx) + Math.Abs(sy - ty) > 1)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 2)
{
if (Math.Abs(sx - tx) != 1 || Math.Abs(sy - ty) != 1)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 3)
{
if (Math.Abs(sx - tx) != 2 || Math.Abs(sy - ty) != 2)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
if (m[(sx + tx) / 2, (sy + ty) / 2] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 4)
{
if (!(Math.Abs(sx - tx) == 2 && Math.Abs(sy - ty) == 1) && !(Math.Abs(sx - tx) == 1 && Math.Abs(sy - ty) == 2))
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
if (Math.Abs(sx - tx) > Math.Abs(sy - ty))
{
if (m[sx + (tx - sx) / 2, sy] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (m[sx, sy + (ty - sy) / 2] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
}
else if (type == 5)
{
if (sx != tx && sy != ty)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
bool RookCollide = false;
if (sx != tx)
{
for (int i = Math.Min(sx, tx) + 1; i < Math.Max(sx, tx); i++)
{
if (m[i, sy] != 0)
{
RookCollide = true;
break;
}
}
}
else
{
for (int i = Math.Min(sy, ty) + 1; i < Math.Max(sy, ty); i++)
{
if (m[sx, i] != 0)
{
RookCollide = true;
break;
}
}
}
if (RookCollide)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else if (type == 6)
{
if (!(Math.Abs(sx - tx) == 3 && Math.Abs(sy - ty) == 2) && !(Math.Abs(sx - tx) == 2 && Math.Abs(sy - ty) == 3))
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
int kx = (tx - sx > 0) ? 1 : -1;
int ky = (ty - sy > 0) ? 1 : -1;
if (Math.Abs(sx - tx) > Math.Abs(sy - ty))
{
if (m[sx + kx, sy] != 0 || m[sx + 2 * kx, sy + ky] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
else
{
if (m[sx, sy + ky] != 0 || m[sx + kx, sy + 2 * ky] != 0)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
}
else if (type == 7)
{
if (Math.Abs(sx - tx) > 1 || Math.Abs(sy - ty) > 1)
{
Console.WriteLine("Invalid command");
isInvalid = true;
return;
}
}
knockOut = m[tx, ty];
m[tx, ty] = m[sx, sy];
m[sx, sy] = 0;
}
public bool CheckMate(int k)
{
int x = 0, y = 0;
for (int i = 0; i <= 8; i++)
{
for (int j = 0; j <= 9; j++)
{
if (m[i, j] == (k ^ 1) * 10 + 1)
{
x = i; y = j;
break;
}
}
}
bool flag = false;
for (int i = x + 1; i <= 8; i++)
{
if (m[i, y] == k * 10 + 5)
{
flag = true;
break;
}
else if (m[i, y] != 0) break;
}
for (int i = x - 1; i >= 0; i--)
{
if (m[i, y] == k * 10 + 5)
{
flag = true;
break;
}
else if (m[i, y] != 0) break;
}
for (int i = y + 1; i <= 9; i++)
{
if (m[x, i] == k * 10 + 5)
{
flag = true;
break;
}
else if (m[x, i] != 0) break;
}
for (int i = y - 1; i >= 0; i--)
{
if (m[x, i] == k * 10 + 5)
{
flag = true;
break;
}
else if (m[x, i] != 0) break;
}
if (flag) return flag;
if (x <= 7 && m[x + 1, y] == k * 10 + 1) flag = true;
if (y <= 8 && m[x, y + 1] == k * 10 + 1) flag = true;
if (x >= 1 && m[x - 1, y] == k * 10 + 1) flag = true;
if (y >= 1 && m[x, y - 1] == k * 10 + 1) flag = true;
if (flag) return flag;
if (x <= 7 && y <= 8 && m[x + 1, y + 1] == k * 10 + 2) flag = true;
if (x >= 1 && y <= 8 && m[x - 1, y + 1] == k * 10 + 2) flag = true;
if (x <= 7 && y >= 1 && m[x + 1, y - 1] == k * 10 + 2) flag = true;
if (x >= 1 && y >= 1 && m[x - 1, y - 1] == k * 10 + 2) flag = true;
if (flag) return flag;
if (x <= 7 && m[x + 1, y] == k * 10 + 7) flag = true;
if (y <= 8 && m[x, y + 1] == k * 10 + 7) flag = true;
if (x >= 1 && m[x - 1, y] == k * 10 + 7) flag = true;
if (y >= 1 && m[x, y - 1] == k * 10 + 7) flag = true;
if (x <= 7 && y <= 8 && m[x + 1, y + 1] == k * 10 + 7) flag = true;
if (x >= 1 && y <= 8 && m[x - 1, y + 1] == k * 10 + 7) flag = true;
if (x <= 7 && y >= 1 && m[x + 1, y - 1] == k * 10 + 7) flag = true;
if (x >= 1 && y >= 1 && m[x - 1, y - 1] == k * 10 + 7) flag = true;
if (flag) return flag;
if (x <= 6 && y <= 8 && m[x + 2, y + 1] == k * 10 + 4 && m[x + 1, y + 1] == 0) flag = true;
if (x >= 2 && y <= 8 && m[x - 2, y + 1] == k * 10 + 4 && m[x - 1, y + 1] == 0) flag = true;
if (x <= 6 && y >= 1 && m[x + 2, y - 1] == k * 10 + 4 && m[x + 1, y - 1] == 0) flag = true;
if (x >= 2 && y >= 1 && m[x - 2, y - 1] == k * 10 + 4 && m[x - 1, y - 1] == 0) flag = true;
if (x <= 7 && y <= 7 && m[x + 1, y + 2] == k * 10 + 4 && m[x + 1, y + 1] == 0) flag = true;
if (x >= 1 && y <= 7 && m[x - 1, y + 2] == k * 10 + 4 && m[x - 1, y + 1] == 0) flag = true;
if (x <= 7 && y >= 2 && m[x + 1, y - 2] == k * 10 + 4 && m[x + 1, y - 1] == 0) flag = true;
if (x >= 1 && y >= 2 && m[x - 1, y - 2] == k * 10 + 4 && m[x - 1, y - 1] == 0) flag = true;
if (flag) return flag;
if (x <= 6 && y <= 7 && m[x + 2, y + 2] == k * 10 + 3 && m[x + 1, y + 1] == 0) flag = true;
if (x >= 2 && y <= 7 && m[x - 2, y + 2] == k * 10 + 3 && m[x - 1, y + 1] == 0) flag = true;
if (x <= 6 && y >= 2 && m[x + 2, y - 2] == k * 10 + 3 && m[x + 1, y - 1] == 0) flag = true;
if (x >= 2 && y >= 2 && m[x - 2, y - 2] == k * 10 + 3 && m[x - 1, y - 1] == 0) flag = true;
if (flag) return flag;
if (x <= 5 && y <= 7 && m[x + 3, y + 2] == k * 10 + 6 && m[x + 2, y + 2] == 0 && m[x + 1, y + 1] == 0) flag = true;
if (x >= 3 && y <= 7 && m[x - 3, y + 2] == k * 10 + 6 && m[x - 2, y + 2] == 0 && m[x - 1, y + 1] == 0) flag = true;
if (x <= 5 && y >= 2 && m[x + 3, y - 2] == k * 10 + 6 && m[x + 2, y - 2] == 0 && m[x + 1, y - 1] == 0) flag = true;
if (x >= 3 && y >= 2 && m[x - 3, y - 2] == k * 10 + 6 && m[x - 2, y - 2] == 0 && m[x - 1, y - 1] == 0) flag = true;
if (x <= 6 && y <= 6 && m[x + 2, y + 3] == k * 10 + 6 && m[x + 2, y + 2] == 0 && m[x + 1, y + 1] == 0) flag = true;
if (x >= 2 && y <= 6 && m[x - 2, y + 3] == k * 10 + 6 && m[x - 2, y + 2] == 0 && m[x - 1, y + 1] == 0) flag = true;
if (x <= 6 && y >= 3 && m[x + 2, y - 3] == k * 10 + 6 && m[x + 2, y - 2] == 0 && m[x + 1, y - 1] == 0) flag = true;
if (x >= 2 && y >= 3 && m[x - 2, y - 3] == k * 10 + 6 && m[x - 2, y - 2] == 0 && m[x - 1, y - 1] == 0) flag = true;
return flag;
}
public void Write()
{
switch (m[tx, ty])
{
case 1: { Console.Write("red captain;"); break; }
case 2: { Console.Write("red guard;"); break; }
case 3: { Console.Write("red elephant;"); break; }
case 4: { Console.Write("red horse;"); break; }
case 5: { Console.Write("red car;"); break; }
case 6: { Console.Write("red duck;"); break; }
case 7: { Console.Write("red soldier;"); break; }
case 11: { Console.Write("blue captain;"); break; }
case 12: { Console.Write("blue guard;"); break; }
case 13: { Console.Write("blue elephant;"); break; }
case 14: { Console.Write("blue horse;"); break; }
case 15: { Console.Write("blue car;"); break; }
case 16: { Console.Write("blue duck;"); break; }
case 17: { Console.Write("blue soldier;"); break; }
}
switch (knockOut)
{
case 0: { Console.Write("NA;"); break; }
case 1: { Console.Write("red captain;"); break; }
case 2: { Console.Write("red guard;"); break; }
case 3: { Console.Write("red elephant;"); break; }
case 4: { Console.Write("red horse;"); break; }
case 5: { Console.Write("red car;"); break; }
case 6: { Console.Write("red duck;"); break; }
case 7: { Console.Write("red soldier;"); break; }
case 11: { Console.Write("blue captain;"); break; }
case 12: { Console.Write("blue guard;"); break; }
case 13: { Console.Write("blue elephant;"); break; }
case 14: { Console.Write("blue horse;"); break; }
case 15: { Console.Write("blue car;"); break; }
case 16: { Console.Write("blue duck;"); break; }
case 17: { Console.Write("blue soldier;"); break; }
}
if (knockOut == 1 || knockOut == 11) isCaptured = true;
if (!isCaptured && isCheckmate) Console.Write("yes;");
else Console.Write("no;");
if (isCaptured) Console.WriteLine("yes");
else Console.WriteLine("no");
}
}
class MainClass
{
static public int Read()
{
int x = 0;
int c = Console.Read();
while (c < '0' || c > '9') c = Console.Read();
while (c >= '0' && c <= '9')
{
x = (x * 10) + (c - 48);
c = Console.Read();
}
return x;
}
public static void Main(string[] args)
{
Map map = new Map();
map.Init();
int Q = Read();
for (int i = 1; i <= Q; i++)
{
map.Clear();
map.sy = Read();
map.sx = Read();
map.ty = Read();
map.tx = Read();
if (map.isCaptured)
{
Console.WriteLine("Invalid command");
continue;
}
map.CheckOut();
map.Move();
if (map.isInvalid) continue;
map.isCheckmate = map.CheckMate(0) || map.CheckMate(1);
map.Write();
map.side ^= 1;
}
}
}
}
__EOF__

本文链接:https://www.cnblogs.com/kaiserwilheim/p/16482066.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具