|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
//小黄鸭调试法,他不是精神分裂!他只是在debug
|
|
|
//https://www.jianshu.com/p/9317572c438c
|
|
|
|
|
|
// 算法竞赛入门经典(第二版)-刘汝佳-第四章 函数与递归 例题+习题
|
|
|
//https://vjudge.net/contest/106163#overview
|
|
|
|
|
|
//定义初始化数组的简化版本
|
|
|
#define mms(a, b) memset(a,b,sizeof(a))
|
|
|
|
|
|
//递增循环
|
|
|
#define rep(i, n, t) for(int i=(n);i<(t);i++)
|
|
|
//递减循环
|
|
|
#define per(i, n, t) for(int i=(n);i>(t);i--)
|
|
|
|
|
|
#define N 11 //棋盘的高度
|
|
|
#define M 10 //棋盘的宽度
|
|
|
|
|
|
//似乎还有问题,比如黑方将走时,可能吃掉了红方的棋子,这样整个棋盘需要进行一些修改,但这个程序没有进行处理。
|
|
|
|
|
|
//棋盘
|
|
|
char chessboard[N][M];
|
|
|
|
|
|
//是不是被将死
|
|
|
bool cheakmeat = true;
|
|
|
|
|
|
//是不是出界
|
|
|
bool cheak(int x, int y) {
|
|
|
if (x < N && x >= 1 && y < M && y >= 1) return true;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//判断黑方的将是不是可以走到这个位置,因为虽然象棋中的将可以向周边四个方向走动,但不能出了九宫格,也就是有X,Y的范围限定。
|
|
|
bool cheakjiang(int x, int y) {
|
|
|
if (x <= 3 && x >= 1 && y <= 6 && y >= 4) return true;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//判帅
|
|
|
bool judgeG(int x, int y) {
|
|
|
rep(i, x + 1, N) {
|
|
|
if (chessboard[i][y] == 0) {} //这一行的这一列没有棋子
|
|
|
else if (chessboard[i][y] == 'G') return true; //如果存在红方的帅,直接返回吧,不用继续判断,
|
|
|
// 这个其实实现的不怎么样,因为(1)浪费,红的就帅,不用从x+1判断,因为棋盘的最下方三行是红方帅的势力范围,出不了界。
|
|
|
// (2)实现的不怎么清晰
|
|
|
else return false;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//判马
|
|
|
bool judgeH(int x, int y) {
|
|
|
//马能走的8个方向
|
|
|
int temp[8][8]{{1, -2},//右1下
|
|
|
{-1, -2}, //左1下
|
|
|
{2, -1},//右2上
|
|
|
{-2, -1},//左2上
|
|
|
{-2, 1}, //左2下
|
|
|
{2, 1}, //右2上
|
|
|
{-1, 2}, //左1下
|
|
|
{1, 2}}; //右1下
|
|
|
//遍历8个方向
|
|
|
rep(i, 0, 8) {
|
|
|
int xx = x + temp[i][0];
|
|
|
int yy = y + temp[i][1];
|
|
|
//如果没有出界的话
|
|
|
if (cheak(xx, yy)) {
|
|
|
if (chessboard[xx][yy] == 0) {} //这个位置没有棋子,可以走
|
|
|
else if (chessboard[xx][yy] == 'H') //如果进入马的攻击范围
|
|
|
{
|
|
|
//判断是不是别马腿
|
|
|
int x2 = (temp[i][0] * -1) / 2;
|
|
|
int y2 = (temp[i][1] * -1) / 2;
|
|
|
if (chessboard[xx + x2][yy + y2] == 0) //不存在别马腿的
|
|
|
return true;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//判车
|
|
|
bool judgeR(int x, int y) {
|
|
|
//上方每一行,y这一列,是不是有车
|
|
|
per(i, x - 1, 0) {
|
|
|
if (chessboard[i][y] == 0) {}
|
|
|
else if (chessboard[i][y] == 'R') return true;
|
|
|
else break;
|
|
|
}
|
|
|
//下方每一行,y这一列,是不是有车
|
|
|
rep(i, x + 1, N) {
|
|
|
if (chessboard[i][y] == 0) {}
|
|
|
else if (chessboard[i][y] == 'R') return true;
|
|
|
else break;
|
|
|
}
|
|
|
|
|
|
//行上是不是有车?从右向左找车车
|
|
|
per(j, y - 1, 0) {
|
|
|
if (chessboard[x][j] == 0) {}
|
|
|
else if (chessboard[x][j] == 'R' && j != y) return true;
|
|
|
else break;
|
|
|
}
|
|
|
//行上是不是有车?从左向右找车车
|
|
|
rep(j, y + 1, M) {
|
|
|
if (chessboard[x][j] == 0) {}
|
|
|
else if (chessboard[x][j] == 'R' && j != y) return true;
|
|
|
else return false;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//判炮(隔山打,所以cnt==2才能形成攻击力量!也是四个方向,两横两纵)
|
|
|
bool judgeC(int x, int y) {
|
|
|
int cnt = 0;
|
|
|
per(i, x - 1, 0) {
|
|
|
if (chessboard[i][y] == 0) {}
|
|
|
else {
|
|
|
cnt++;
|
|
|
if (chessboard[i][y] == 'C') { if (cnt == 2) return true; }
|
|
|
}
|
|
|
}
|
|
|
cnt = 0;
|
|
|
rep(i, x + 1, N) {
|
|
|
if (chessboard[i][y] == 0) {}
|
|
|
else {
|
|
|
cnt++;
|
|
|
if (chessboard[i][y] == 'C') { if (cnt == 2) return true; }
|
|
|
}
|
|
|
}
|
|
|
cnt = 0;
|
|
|
per(j, y - 1, 0) {
|
|
|
if (chessboard[x][j] == 0) {}
|
|
|
else {
|
|
|
cnt++;
|
|
|
if (chessboard[x][j] == 'C') { if (cnt == 2) return true; }
|
|
|
}
|
|
|
}
|
|
|
cnt = 0;
|
|
|
rep(j, y + 1, M) {
|
|
|
if (chessboard[x][j] == 0) {}
|
|
|
else {
|
|
|
cnt++;
|
|
|
if (chessboard[x][j] == 'C') { if (cnt == 2) return true; }
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//功能:判断的主体函数,是至顶向下进行梳理逻辑的主体
|
|
|
void judge(int x, int y) // x+y-->黑方将的位置
|
|
|
{
|
|
|
int temp[4][4]
|
|
|
{
|
|
|
{0, -1}, //向上
|
|
|
{0, 1}, //向下
|
|
|
{-1, 0}, //向左
|
|
|
{1, 0} //向右
|
|
|
};
|
|
|
//如果是与红方帅对脸了,那么被将死
|
|
|
if (judgeG(x, y)) {
|
|
|
cheakmeat = false;
|
|
|
return;
|
|
|
}
|
|
|
//向四个方向逐个尝试
|
|
|
rep(i, 0, 4) {
|
|
|
if (cheakjiang(x + temp[i][0], y + temp[i][1])) //判断这个将,是不是可以走到这个位置,不能走的不进行循环体
|
|
|
{
|
|
|
//如果被对方红棋的帅将死,那么不用继续判断,尝试其它方向去吧~
|
|
|
if (judgeG(x + temp[i][0], y + temp[i][1])) continue;
|
|
|
else if (judgeH(x + temp[i][0], y + temp[i][1])) continue; //判断是不是被马将死
|
|
|
else if (judgeR(x + temp[i][0], y + temp[i][1])) continue; //判断是不是被车将死
|
|
|
else if (judgeC(x + temp[i][0], y + temp[i][1])) continue; //判断是不是被炮将死
|
|
|
//都没有被将死,那么是可以走这个位置的,所以cheakmeat=false,而且,一旦找到方法,就没有必要继续检查其它位置了~
|
|
|
cheakmeat = false;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//结果向量
|
|
|
vector<string> V;
|
|
|
|
|
|
int main() {
|
|
|
//读入红棋的个数n; x+y-->黑棋将的位置
|
|
|
int x, y, n;
|
|
|
while (cin >> n >> x >> y) {
|
|
|
if (!n && !x && !y) break; //如果有0或负数出现,则退出
|
|
|
else {
|
|
|
//初始化
|
|
|
cheakmeat = true;
|
|
|
//初始化棋盘
|
|
|
mms(chessboard, 0);
|
|
|
|
|
|
//输入
|
|
|
rep(i, 0, n) //递增循环,第一个参数是递增变量,第二个参数是开始值,第三个变量是结束值
|
|
|
{
|
|
|
int a, b;
|
|
|
char size;
|
|
|
// size--> 炮,马,车
|
|
|
// a+b--> 棋子的位置
|
|
|
cin >> size >> a >> b;
|
|
|
//放入棋盘中
|
|
|
chessboard[a][b] = size;
|
|
|
}
|
|
|
//判断是不是将死了,如果将死了,修改全局变量cheakmeat-->true,否则修改为false
|
|
|
judge(x, y);
|
|
|
//输出
|
|
|
if (cheakmeat) V.push_back("YES"); //之所有用向量vector来装每一局的结果,是因为输入的残局数量不一定,用数组之类不方便,动态的容器方便些
|
|
|
else V.push_back("NO");
|
|
|
}
|
|
|
}
|
|
|
//输出结果
|
|
|
rep(i, 0, V.size()) {
|
|
|
//输出结果
|
|
|
cout << V[i] << endl;
|
|
|
}
|
|
|
return 0;
|
|
|
} |