主要考虑两点:
1. 不管红方还是黑方都可以飞将(若两将间有棋子就不行)
2. 攻击的点9个,不管9个点红方有没有棋子只要红方能攻到就记录
比如下面这个图红方(8,4)可以攻击点(2,4),虽然点(2,4)有红方的棋子(车)但应把这个点记录下来, 表示黑将不能吃点(2,4)的车
主要的两点考虑进去了就行(该图红方可以将死)
参考代码如下:
#include
using namespace std;
const char* s = "GRCH";
const int f1[] = { -2, -2, 2, 2, -1, 1, -1, 1 };
const int g1[] = { -1, 1, -1, 1, -2, -2, 2, 2 };
const int f[] = { -1, 1, 0, 0 };
const int g[] = { 0, 0, -1, 1 };
const int M = 10, N = 9;
int plat[M + 1][N + 1];
bool isVisit[M + 1][N + 1];
bool isExist(int x, int y) {
return x > 0 && x <= M && y > 0 && y <= N;
}
bool isAttack(int x, int y) {
return x >= 1 && x <= 3 && y >= 4 && y <= 6;
}
//Horse
void horseAttact(int x, int y) {
for (int i = 0; i < 4; ++i) {
int fx = x + f[i], gy = y + g[i];
if (isExist(fx, gy) && !plat[fx][gy]) {
int a = x + f1[i * 2], b = y + g1[i * 2];
int c = x + f1[i * 2 + 1], d = y + g1[i * 2 + 1];
if (isAttack(a, b)) isVisit[a][b] = true;
if (isAttack(c, d)) isVisit[c][d] = true;
}
}
}
//Chariot
void chariotAttack(int x, int y) {
for (int i = 0; i < 4; ++i) {
int a = f[i], b = g[i];
int fx = x + a, gy = y + b;
while (isExist(fx, gy)) {
if (isAttack(fx, gy)) isVisit[fx][gy] = true;
if (plat[fx][gy]) break;
fx += a;
gy += b;
}
}
}
//Cannon
void cannonAttack(int x, int y) {
for (int i = 0; i < 4; ++i) {
int a = f[i], b = g[i];
int fx = x + a, gy = y + b;
while (isExist(fx, gy) && !plat[fx][gy]) {
fx += a;
gy += b;
}
fx += a;
gy += b;
while (isExist(fx, gy)) {
if (isAttack(fx, gy)) isVisit[fx][gy] = true;
if (plat[fx][gy]) break;
fx += a;
gy += b;
}
}
}
//Red General flying general
void redGeneralAttack(int x, int y) {
for (int i = x - 1; i > 0; --i) {
if (isAttack(i, y)) isVisit[i][y] = true;
if (plat[i][y]) return;
}
}
//Black General flying general
//If the Black General can fly, return false
bool blackGeneralAttack(int blackX, int redX, int y) {
for (int i = blackX + 1; i < redX; ++i)
if (plat[i][y]) return true;
return false;
}
void (*attack[])(int, int) = { 0, chariotAttack, cannonAttack, horseAttact };
int main() {
int n, blackX, blackY, redX, redY, c, x, y;
while (scanf("%d%d%d", &n, &blackX, &blackY), n) {
memset(plat, 0, sizeof(plat));
memset(isVisit, 0, sizeof(isVisit));
while (n--) {
while ((c = getchar()) && isspace(c)) ;
scanf("%d%d", &x, &y);
if (c == s[0]) { redX = x; redY = y; }
else for (int i = 1; i < 4; ++i)
if (c == s[i]) { plat[x][y] = i; break; }
}
for (int i = 1; i <= M; ++i)
for (int j = 1; j <= N; ++j)
for (int k = 1; k < 4; ++k)
if (plat[i][j] == k) (*attack[k])(i, j);
redGeneralAttack(redX, redY);
bool ok = true;
if (redY == blackY) ok = blackGeneralAttack(blackX, redX, redY);
for (int i = 0; i < 4; ++i) {
int fx = blackX + f[i], gy = blackY + g[i];
if (isAttack(fx, gy) && !isVisit[fx][gy]) { ok = false; break; }
}
printf("%s\n", ok ? "YES" : "NO");
}
return 0;
}