#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int table[11][10];
//obstacle函数返回棋盘上某一行或某一列,a和b两个棋子间其他棋子数目
//flag=0表示行,flag=1表示列,num是对应的行/列号
int obstacle(int flag,int num,int a,int b)
{
int count=0,i,c;
if(a>b){
c=a;
a=b;
b=c;
}
if(!flag){
for(i=a+1;i<b;i++){
if(table[num][i])
count++;
}
}
else{
for(i=a+1;i<b;i++){
if(table[i][num])
count++;
}
}
return count;
}
int main()
{
//freopen("input.txt","r",stdin);
//黑帅移动方向
int direction[4][2]={-1,0,
0,-1,
0,1,
1,0};
//马能将到黑帅时黑帅相对于马的偏移量以及蹩脚点位置相对于马的偏移量
int horse[8][4]={1,2,0,1,
2,1,1,0,
2,-1,1,0,
1,-2,0,-1,
-1,2,0,1,
-2,1,-1,0,
-2,-1,-1,0,
-1,-2,0,-1};
int n,a,b,x,y,i,j,k,flag;
char ch[7];//7个红子代号
int pos[7][2];//7个红子位置
while(cin>>n>>a>>b){
if(n==0)
break;
memset(table,0,sizeof(table));
for(i=0;i<n;i++){
cin>>ch[i]>>pos[i][0]>>pos[i][1];
table[pos[i][0]][pos[i][1]]=1;
}
for(i=0;i<4;i++){
//越界判定
x=a+direction[i][0];
y=b+direction[i][1];
//考虑了黑帅在棋盘两头的情形
if(a<5&&(x<1||x>3)||a>5&&(x<8||x>10)||y<4||y>6)
continue;
flag=1;
//对于每一种移动情况,逐个判定移动之后是否被n个红子之一将军
for(j=0;j<n;j++){
int eat=0,temp0,temp1;
//判断是否发生吃子,如是则更新pos和table,重新开始
if(x==pos[j][0]&&y==pos[j][1]){
eat=1;
temp0=pos[j][0],temp1=pos[j][1];
table[pos[j][0]][pos[j][1]]=0;
pos[j][0]=100,pos[j][1]=100;
j=-1;
continue;
}
if(ch[j]=='R'){
if(pos[j][0]==x&&obstacle(0,x,pos[j][1],y)==0||pos[j][1]==y&&obstacle(1,y,pos[j][0],x)==0){
flag=0;
break;
}
}
else if(ch[j]=='G'){
if(pos[j][1]==y&&obstacle(1,y,pos[j][0],x)==0){
flag=0;
break;
}
}
else if(ch[j]=='C'){
if(pos[j][0]==x&&obstacle(0,x,pos[j][1],y)==1||pos[j][1]==y&&obstacle(1,y,pos[j][0],x)==1){
flag=0;
break;
}
}
else{
for(k=0;k<8;k++){
if(x==pos[j][0]+horse[k][0]&&y==pos[j][1]+horse[k][1]&&table[pos[j][0]+horse[k][2]][pos[j][1]+horse[k][3]]==0){
flag=0;
break;
}
}
}
if(eat){
//恢复pos和table
pos[j][0]=temp0,pos[j][1]=temp1;
table[pos[j][0]][pos[j][1]]=1;
}
}
if(flag)
break;
}
if(!flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
UVA - 1589 Xiangqi
最新推荐文章于 2020-05-16 20:55:06 发布