思路:
依次考虑红方车马炮帅,标记他们能攻击到的范围。
车和将都在遇到第一个棋时停止,但要注意,第一个棋所在的位置需要被标记为可攻击,因为可能被老王吃掉。
炮类似。
马无脑模拟。
以上因为题目保证被将军,所以都未考虑黑将。
之后判断黑将所能到达的位置是否处于红方攻击范围。
#include <cstdio>
#include <cstring>
#include <cctype>
const int MAXKIND = 4;
const int MAXNUM = 2;
const int MINROW = 1;
const int MAXROW = 10;
const int MINCOL = 1;
const int MAXCOL = 9;
struct Point
{
int ro, co;
}chess[MAXKIND+2][MAXNUM+2];
bool occu[MAXROW+2][MAXCOL+2];
char board[MAXROW+2][MAXCOL+2];
int count[MAXKIND];
bool in_palace(int r, int c)
{
if (r >= 1 && r <= 3 && c <= 6 && c >= 4) return true;
else return false;
}
int readchar()
{
int t;
while (t = getchar())
{
if (isalpha(t)) break;
}
return t;
}
int to_num(char t)
{
switch(t)
{
case 'G':
return 0;
case 'R':
return 1;
case 'H':
return 2;
case 'C':
return 3;
}
}
void go_general()
{
int cnt = 0;
int r, c;
while ((r = chess[0][cnt].ro) && (c = chess[0][cnt].co ))
{
cnt++;
for (int i = r - 1; i >= MINROW && (board[i+1][c] == 'G' || !board[i+1][c]); i--)
{
occu[i][c] = true;
}
}
}
void go_chariot()
{
int cnt = 0;
int r, c;
while ((r = chess[1][cnt].ro) && (c = chess[1][cnt].co))
{
cnt++;
for (int i = r-1; i >= MINROW && (board[i+1][c] == 'R' || !board[i+1][c]); i--)
{
occu[i][c] = true;
}
for (int i = r+1; i <= MAXROW && (board[i-1][c] == 'R' || !board[i-1][c]); i++)
{
occu[i][c] = true;
}
for (int j = c-1; j >= MINCOL && (board[r][j+1] == 'R' || !board[r][j+1]); j--)
{
occu[r][j] = true;
}
for (int j = c+1; j <= MAXCOL && (board[r][j-1] == 'R' || !board[r][j-1]); j++)
{
occu[r][j] = true;
}
}
}
void go_horse()
{
int cnt = 0;
int r, c;
while ((r = chess[2][cnt].ro ) && (c = chess[2][cnt].co))
{
cnt++;
if (!board[r][c+1])
{
if (in_palace(r-1, c+2)) occu[r-1][c+2] = true;
if (in_palace(r+1, c+2)) occu[r+1][c+2] = true;
}
if (!board[r+1][c])
{
if (in_palace(r+2, c-1)) occu[r+2][c-1] = true;
if (in_palace(r+2, c+1)) occu[r+2][c+1] = true;
}
if (!board[r][c-1])
{
if (in_palace(r-1, c-2)) occu[r-1][c-2] = true;
if (in_palace(r+1, c-2)) occu[r+1][c-2] = true;
}
if (!board[r-1][c])
{
if (in_palace(r-2, c-1)) occu[r-2][c-1] = true;
if (in_palace(r-2, c+1)) occu[r-2][c+1] = true;
}
}
}
void go_cannon()
{
int cnt = 0;
int r, c;
int mark = 0;
while ((r = chess[3][cnt].ro) && (c = chess[3][cnt].co))
{
cnt++;
mark = 0;
for (int i = r-1; i >= MINROW; i--)
{
if (mark) occu[i][c] = true;
if (board[i][c] && ++mark == 2) break;
}
mark = 0;
for (int i = r+1; i <= MAXROW; i++)
{
if (mark) occu[i][c] = true;
if (board[i][c] && ++mark == 2) break;
}
mark = 0;
for (int j = c-1; j >= MINCOL; j--)
{
if (mark) occu[r][j] = true;
if (board[r][j] && ++mark == 2) break;
}
mark = 0;
for (int j = c+1; j <= MAXCOL; j++)
{
if (mark) occu[r][j] = true;
if (board[r][j] && ++mark == 2) break;
}
}
}
int ROW[] = {0, 0, 1, -1};
int COL[] = {1, -1, 0, 0};
bool if_live(int r, int c)
{
for (int i = 0; i < 4; i++)
{
if (in_palace(r+ROW[i], c+COL[i]) && !occu[r+ROW[i]][c+COL[i]])
return true;
}
return false;
}
int main()
{
int n;
int x, y;
while (scanf("%d%d%d", &n, &x, &y) && n && x && y)
{
// init
memset(chess, 0, sizeof(chess));
memset(count, 0, sizeof(count));
memset(board, 0, sizeof(board));
memset(occu, 0, sizeof(occu));
//input
for (int i = 1; i <= n; i++)
{
char t;
int tr, tc;
int tnum;
t = readchar();
scanf("%d%d", &tr, &tc);
board[tr][tc] = t;
tnum = to_num(t);
chess[tnum][count[tnum]].ro = tr;
chess[tnum][count[tnum]++].co = tc;
}
//work
go_general();
go_chariot();
go_horse();
go_cannon();
//print
printf("%s\n", (if_live(x, y)) ? "NO" : "YES");
}
return 0;
}