#include 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 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; }