象棋, 判断红棋是否能将死黑棋
因为轮到黑棋下了, 黑棋只有四种下法, 所以只需判断黑将往四个方向走一步后的情况即可(这里卡了好久, 一直把当前的状况也用来判断了)
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <list>
using namespace std;
const int MAXN = 40+10;
const int ROW = 10;
const int COL = 9;
const int Base = 1000;
typedef long long LL;
/*
错误点: 1. 当前状况不需要检查, 只需要检查黑将向四个方向走一步之后的情况即可
2. 看清楚输出的字母的大小写, OJ无法自动转换输出的大小写
*/
char Map[MAXN][MAXN];
int Red[MAXN];
int N;
int Move[8][2] = { {-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2} };
int Dir[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
int Between(char type,int num,int from,int to){
if( from>to ){
int t = to;
to = from;
from = t;
}
int cnt = 0;
if( type=='R' ){
for(int i=from+1; i<to; i++){
if( Map[num][i]!=0 ){
cnt++;
}
}
}else{
for(int i=from+1; i<to; i++){
if( Map[i][num]!=0 ){
cnt++;
}
}
}
return cnt;
}
bool isCheckmate(int black_r,int black_c){
// 若红棋走一步棋可以吃黑将, 则返回true
bool flag = false;
for(int i=0; i<N; i++){
int red_r = Red[i]/Base, red_c = Red[i]%Base;
if( red_r==black_r && red_c==black_c ) continue;
char type = Map[red_r][red_c];
if( type=='G' ){
if( red_c==black_c && Between('C',red_c,red_r,black_r)==0 ){
flag = true;
}
}else if( type=='R' ){
if( red_c==black_c && Between('C',red_c,red_r,black_r)==0 ){
flag = true;
}else if( red_r==black_r && Between('R',red_r,red_c,black_c)==0 ){
flag = true;
}
}else if( type=='C' ){
if( red_c==black_c && Between('C',red_c,red_r,black_r)==1 ){
flag = true;
}else if( red_r==black_r && Between('R',red_r,red_c,black_c)==1 ){
flag = true;
}
}else if( type=='H' ){
for(int j=0; j<8; j++){
int nextr = red_r+Move[j][0];
int nextc = red_c+Move[j][1];
if( nextr<1 || nextr>ROW || nextc<1 || nextc>COL ) continue;
if( black_r==nextr && black_c==nextc ){
int d = j/2;
if( Map[(red_r+Dir[d][0])][(red_c+Dir[d][1])]==0 ){
flag = true;
}
}
}
}
}
return flag;
}
int main(){
// freopen("input.txt","r",stdin);
// freopen("myoutput.txt","w",stdout);
int gr, gc;
// int Case = 0;
cin >> N >> gr >> gc;
while( !( N==0&&gr==0&&gc==0 ) ){
memset(Map,0,sizeof(Map));
memset(Red,0,sizeof(Red));
int r,c;
char ch;
for(int i=0; i<N; i++){
cin >> ch >> r >> c;
Red[i] = r*Base + c;
Map[r][c] = ch;
}
bool result = true;
for( int i=0; i<4; i++){
int nextr = gr+Dir[i][0];
int nextc = gc+Dir[i][1];
if( nextr>=1 && nextr<=3 && nextc>=4 && nextc<=6 ){
if( !isCheckmate(nextr,nextc) ){
// printf("Could move to (%d,%d)\n",nextr,nextc);
result = false;
// break;
}
}
}
cout << ( result==true? "YES":"NO" ) << endl;
cin >> N >> gr >> gc;
}
return 0;
}