#include
using namespace std;
int main()
{int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//将的走向
int dre[4][2]= {{1,2},{-1,2},{-1,-2},{1,-2}};//马的走向
int d[4][2]= {{2,1},{-2,1},{-2,-1},{2,-1}};
class point
{ char s[5];
int x,y;
}
r[10],rec[10];
int map[20][20];//表示有没有棋子
int bx,by;//黑方老将的位置
bool a[10];
bool is_in(point a)
{
return (a.x<=3&&a.x>=1&&a.y>=4&&a.y<=6) ;
}
bool is_inside(point a)
{
return (a.x>=1&&a.x<=10&&a.y>=1&&a.y<=9);
}
bool defeat(point hei,point hong) //hei即表示黑方老将,hong表示当前用这个hong可不可以将黑方老将杀死
{int i,j,k;
int minx=min(hong.x,hei.x);
int maxx=max(hong.x,hei.x);
int miny=min(hong.y,hei.y);
int maxy=max(hong.y,hei.y);
if(hong.s[0]=='R')//车
{//车有车的杀法
if(hong.x==hei.x)
{//车与黑将的x相同,那么看看同x行上是否有阻挡棋子
for(i=miny+1; i<maxy; i++)
if(map[hei.x][i])
return false;
return true;
}
else if(hong.y==hei.y)
{
for(i=minx+1; i<maxx; i++)
if(map[i][hei.y])
return false;
return true;
}
return false;
}
int cnt;
if(hong.s[0]=='C')//炮
{//炮的杀法与车的杀法有点类似,车是需要判断中间有没有阻挡,而炮必须有阻挡(即跑架子)
if(hong.x==hei.x)
{
cnt=0;
for(i=miny+1; i
if(map[hei.x][i])
cnt++;
if(cnt==1)
return true;
return false;
}
else if(hong.y==hei.y)
{ cnt=0;
for(i=minx+1; i
if(map[i][hei.y])
cnt++;
if(cnt==1)
return true;
return false;
}
else return false;
}
point tmp,up;
if(hong.s[0]=='H')//马
{//马的杀法有点特别,先判断绝对值是否在“日"子范围内,然后再分别判断马是否能走到
if(abs(hong.x-hei.x)==1&&abs(hong.y-hei.y)==2)
{
for(i=0; i
{
tmp.x=hei.x+dre[i][0];
tmp.y=hei.y+dre[i][1];
if(is_inside(tmp)&&tmp.x==hong.x&&tmp.y==hong.y)
{//处理有没有蹩马腿的现象,被黑方老将斩杀的不会影响,因为老将已经替代了他的位置
if(tmp.y
{
if(!map[tmp.x][tmp.y+1])
return true;
}
else
{
if(!map[tmp.x][tmp.y-1])
return true;
}
}
}
}
else if(abs(hong.x-hei.x)==2&&abs(hong.y-hei.y)==1)
{
for(i=0; i
{
tmp.x=hei.x+d[i][0];
tmp.y=hei.y+d[i][1];
if(is_inside(tmp)&&tmp.x==hong.x&&tmp.y==hong.y)
{
if(tmp.x
{
if(!map[tmp.x+1][tmp.y])
return true;
}
else
{
if(!map[tmp.x-1][tmp.y])
return true;
}
}
}
return false;
}
return false;
}
if(hong.s[0]=='G')//将
{//老将的杀法也比较好判断,同行或者同列就好;中间没有阻挡
if(hong.y==hei.y)
{
for(i=minx+1; i
{
if(map[i][hei.y])
return false;
}
return true;
}
else return false;
}
}
int main()
{
int n,i,j,k;
while(cin>>n>>bx>>by,(n+bx+by))
{
memset(map,0,sizeof(map));
for(i=1; i<=n; i++)
{
cin>>r[i].s>>r[i].x>>r[i].y;
map[r[i].x][r[i].y]=1;//记录当前位置有没有棋子
}
point tmp;
int tot=1;
memset(vis,0,sizeof(vis));
memset(rec,0,sizeof(rec));
for(i=0; i<4; i++)
{
tmp.x=bx+dir[i][0];
tmp.y=by+dir[i][1];
if(is_in(tmp))
{//记录黑方老将可能的位置
rec[tot++]=tmp;
}
}
bool flag;
for(i=1; i<tot; i++)
{///枚举黑方老将可能的位置,然后判断是否能被杀死
flag=false;
for(j=1; j<=n; j++)
{///枚举红方的棋子可不可以杀死黑方当前位置的老将!
///线面这一句很棒,一修改就AC了,如果当前黑将所在的位置和当前红方棋子相同,
///说明当前红方的这一棋子已经被黑方老将杀死,不能再用它判断是不是可以斩杀黑将
if(rec[i].x==r[j].x&&rec[i].y==r[j].y) continue;
if(defeat(rec[i],r[j]))
{ flag=true;
break;
}
}
if(!flag)
}
if(!flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}