1 条题解
-
0
题解思路
本题需要判断黑方将是否处于“将死”状态,即所有合法移动后的位置均被红方棋子攻击。解题关键在于模拟黑将的所有合法移动,并逐一判断每个新位置是否安全。
方法思路
- 合法移动生成:黑将只能在九宫格((x \in [1,3], y \in [4,6]))内上下左右移动一格,生成所有可能的新位置。
- 攻击判定:
- 飞将(红将G):红将与黑将在同一竖线((y)相同)且中间无棋子。
- 车(R):与黑将在同一行或列,且中间无棋子。
- 炮(C):与黑将在同一行或列,且中间恰好有一个棋子。
- 马(H):符合“日”字移动,且“马腿”位置无棋子。
- 安全检查:对每个新位置,若未被任何红方棋子攻击,则黑方存在安全移动,直接返回“NO”;若所有移动均被攻击,返回“YES”。
解决代码
#include<iostream> #include<cstring> #include<string> using namespace std; int map[13][13]; //初始化为0,1表示有棋子 int sign[13][13]; //初始化为0,1表示在红方棋子攻击范围内 struct node { char c; int x, y; }; int main() { int n, bx, by; while (cin >> n >> bx >> by&&n) { memset(map, 0, sizeof(map)); //初始化 memset(sign, 0, sizeof(sign)); node qizi[10]; int rjx, rjy; for (int i = 0; i < n; i++) { cin >> qizi[i].c >> qizi[i].x >> qizi[i].y; if (qizi[i].c == 'G') { rjx = qizi[i].x; rjy = qizi[i].y; } map[qizi[i].x][qizi[i].y] = 1; } if (rjy == by) //对特殊情况,黑将和红帅如果直接相对,直接是NO { int ok = 0; for (int i = bx + 1; i < rjx; i++) if (map[i][rjy]) ok = 1; if (!ok) { cout << "NO" << endl; continue; } } for (int i = 0; i < n; i++) //处理出红方棋子的攻击范围,棋子本身不在其内(可以被吃) { if (qizi[i].c == 'G') //处理出将的攻击范围 { for (int i = rjx - 1; i >= bx; i--) { sign[i][rjy] = 1; if (map[i][rjy]) break; } } else if (qizi[i].c == 'R') //处理出车的攻击范围 { int xx = qizi[i].x; int yy = qizi[i].y; for (int i = xx + 1; i <= 10; i++) { sign[i][yy] = 1; if (map[i][yy]) break; } for (int i = xx - 1; i >= 1; i--) { sign[i][yy] = 1; if (map[i][yy]) break; } for (int i = yy + 1; i <= 9; i++) { sign[xx][i] = 1; if (map[xx][i]) break; } for (int i = yy - 1; i >= 1; i--) { sign[xx][i] = 1; if (map[xx][i]) break; } } if (qizi[i].c == 'C') //处理出炮的攻击范围 { int xx = qizi[i].x; int yy = qizi[i].y; int ok; ok = 0; for (int i = xx + 1; i <= 10; i++) { if (ok == 1) sign[i][yy] = 1; if (map[i][yy]) ok++; } ok = 0; for (int i = xx - 1; i >= 1; i--) { if (ok == 1) sign[i][yy] = 1; if (map[i][yy]) ok++; } ok = 0; for (int i = yy + 1; i <= 9; i++) { if (ok == 1) sign[xx][i] = 1; if (map[xx][i]) ok++; } ok = 0; for (int i = yy - 1; i >= 1; i--) { if (ok == 1) sign[xx][i] = 1; if (map[xx][i]) ok++; } } if (qizi[i].c == 'H') //处理出马的攻击范围 { int xx = qizi[i].x; int yy = qizi[i].y; if (!map[xx - 1][yy]) { if (xx - 2 >= 1 && yy - 1 >= 1) sign[xx - 2][yy - 1] = 1; if (xx - 2 >= 1 && yy + 1 <= 9) sign[xx - 2][yy + 1] = 1; } if (!map[xx + 1][yy]) { if (xx + 2 <= 10 && yy - 1 >= 1) sign[xx + 2][yy - 1] = 1; if (xx + 2 <= 10 && yy + 1 <= 9) sign[xx + 2][yy + 1] = 1; } if (!map[xx][yy - 1]) { if (yy - 2 >= 1 && xx - 1 >= 1) sign[xx - 1][yy - 2] = 1; if (yy - 2 >= 1 && xx + 1 <= 10) sign[xx + 1][yy - 2] = 1; } if (!map[xx][yy + 1]) { if (yy + 2 <= 9 && xx - 1 >= 1) sign[xx - 1][yy + 2] = 1; if (yy + 2 <= 9 && xx + 1 <= 10) sign[xx + 1][yy + 2] = 1; } } } int cnt = 0; //判断黑将四个方向是否可以走 if (bx - 1 >= 1) { if (sign[bx - 1][by]) cnt++; } else cnt++; if (bx + 1 <= 3) { if (sign[bx + 1][by]) cnt++; } else cnt++; if (by - 1 >= 4) { if (sign[bx][by - 1]) cnt++; } else cnt++; if (by + 1 <= 6) { if (sign[bx][by + 1]) cnt++; } else cnt++; if (cnt == 4) cout << "YES" << endl; else cout << "NO" << endl; } }
- 1
信息
- ID
- 2982
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者