【2019.3.30】
读题二十分钟,写了一个小时,debug了四十分钟,郁闷
思路:
让黑将分别往左、下、右、上四个方向试探:
用checkSafe函数检查黑将在新位置是否安全,如果安全,checkSafe返回true,不安全则返回false
如果四个方向上都不安全,证明红已经把黑将死,输出YES,否则输出NO
checkSafe函数的流程:
1、首先调用checkGeneral查看原位置是否与红帅相对,如果是,证明安全,返回true(因为此时黑将可以一步吃掉红帅)
2、再次调用checkBeyondBound查看新位置是否越界,如果越界,证明不安全,返回false
3、调用checkGeneral查看新位置是否与红帅相对,如果相对,证明这个新位置不安全,返回false
4、调用checkChariot查看新位置是否会被车打,如果会,返回false
5、调用checkCannon查看新位置是否会被炮打,如果会,返回false
6、调用checkHorse查看新位置是否会被马打,如果会,返回false
7、返回true,新位置经检查很安全
值得注意的地方:
1、一定要首先查看原位置是否与红帅相对
2、注意连环炮现象
#include <iostream>
using namespace std;
char board[11][10]; //10*9 board
bool checkSafe(int bx, int by, int d); //检查是否安全
bool checkBeyondBound(int x, int y);//检查黑将越界
bool checkGeneral(int x, int y); //检查帅将相对
bool checkChariot(int x, int y); //检查车
bool checkCannon(int x, int y); //检查炮
bool checkHorse(int x, int y); //检查马
bool checkHorseBound(int hx, int hy); //检查马是否越界
bool isHorse(int hx, int hy); //检查是否是马
bool isEmpty(int hobx, int hoby); //检查马腿是否为空
int main()
{
//freopen("C:\\Users\\Summer\\Desktop\\input.txt", "r", stdin);
//freopen("C:\\Users\\Summer\\Desktop\\output.txt", "w", stdout);
int N, bx, by;
char c;
int rx, ry;
while(cin>>N>>bx>>by && N) {
//初始化
for(int i=0; i<11; i++)
for(int j=0; j<10; j++)
board[i][j]=' ';
//输入棋盘
while(N--) {
cin>>c;
cin>>rx>>ry;
board[rx][ry]=c;
}
//检查黑将向四个方向走一步
//是否会出现安全状态
bool isCheckmate = true;
for(int d=0; d<4; d++) {
if(checkSafe(bx, by, d)) {
isCheckmate = false;
break;
}
}
//如果没出现安全状态,证明将死,输出YES
if(isCheckmate) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
//计算黑将的新位置
int movestep[4][2] =
{
0, -1, //左
+1, 0, //下
0, +1, //右
-1, 0 //上
};
bool checkSafe(int bx, int by, int d)
{
int nx = bx + movestep[d][0];
int ny = by + movestep[d][1];
//cout<<"direction:"<<d<<endl;
if(checkGeneral(bx, by)) return true;
//else cout<<"checkGeneral OK"<<endl;
if(checkBeyondBound(nx, ny)) return false;
//else cout<<"checkBound OK"<<endl;
if(checkGeneral(nx, ny)) return false;
//else cout<<"checkGeneral OK"<<endl;
if(checkChariot(nx, ny)) return false;
//else cout<<"checkChariot OK"<<endl;
if(checkCannon(nx, ny)) return false;
//else cout<<"checkCannon OK"<<endl;
if(checkHorse(nx, ny)) return false;
//else cout<<"checkHorse OK"<<endl;
return true;
}
bool checkBeyondBound(int x, int y)
{
return !(x>=1 && x<=3 && y>=4 && y<=6);
}
//检查同列是否与帅相对(从x往下找)
bool checkGeneral(int x, int y)
{
for(int i=x+1; i<=10; i++) {
if(board[i][y]==' ') continue;
else if(board[i][y]=='G') return true;
else break;
}
return false;
}
//检查同行同列是否有车相对(从x开始往四方找)
bool checkChariot(int x, int y)
{
for(int i=x+1; i<=10; i++) {
if(board[i][y]==' ') continue;
else if(board[i][y]=='R') return true;
else break;
}
for(int i=x-1; i>=1; i--) {
if(board[i][y]==' ') continue;
else if(board[i][y]=='R') return true;
else break;
}
for(int j=y+1; j<=9; j++) {
if(board[x][j]==' ') continue;
else if(board[x][j]=='R') return true;
else break;
}
for(int j=y-1; j>=0; j--) {
if(board[x][j]==' ') continue;
else if(board[x][j]=='R') return true;
else break;
}
return false;
}
//检查同行同列是否与炮相隔一个棋子
bool checkCannon(int x, int y)
{
int cnt=0; //相隔数目
for(int i=x+1; i<=10; i++) {
if(board[i][y]==' ') continue;
else if(cnt==1 && board[i][y]=='C') return true;
else cnt++;
}
cnt=0;
for(int i=x-1; i>=1; i--) {
if(board[i][y]==' ') continue;
else if(cnt==1 && board[i][y]=='C') return true;
else cnt++;
}
cnt=0;
for(int j=y+1; j<=9; j++) {
if(board[x][j]==' ') continue;
else if(cnt==1 && board[x][j]=='C') return true;
else cnt++;
}
cnt=0;
for(int j=y-1; j>=0; j--) {
if(board[x][j]==' ') continue;
else if(cnt==1 && board[x][j]=='C') return true;
else cnt++;
}
return false;
}
//计算马有可能出现的位置
int horseLoca[8][2] =
{
-2, +1, //右上
-2, -1, //左上
-1, -2, //左上
+1, -2, //左下
+2, -1, //左下
+2, +1, //右下
+1, +2, //右下
-1, +2 //右上
};
//计算马腿位置
int hobLoca[8][2] =
{
-1, +1,
-1, -1,
-1, -1,
+1, -1,
+1, -1,
+1, +1,
+1, +1,
-1, +1
};
//检查八个方向的马和蹩马腿位置
bool checkHorse(int x, int y)
{
int hx, hy;
int hobx, hoby;
for(int i=0; i<8; i++) {
hx = x + horseLoca[i][0];
hy = y + horseLoca[i][1];
hobx = x + hobLoca[i][0];
hoby = y + hobLoca[i][1];
if(!checkHorseBound(hx, hy)) continue;
if(isHorse(hx, hy) && isEmpty(hobx, hoby)) return true;
//else cout<<"checkHorse OK:"<<hx<<' '<<hy<<' '<<isHorse(hx, hy)<<' '<<hobx<<' '<<hoby<<' '<<isEmpty(hobx,hoby)<<endl;
}
return false;
}
bool checkHorseBound(int hx, int hy)
{
return (hx>=1 && hx<=10 && hy>=1 && hy<=9);
}
bool isHorse(int hx, int hy)
{
return (board[hx][hy]=='H');
}
bool isEmpty(int hobx, int hoby)
{
return (board[hobx][hoby]==' ');
}