UVa1589

/*
题意很简单,就是黑方只剩下一个将,红方还有很多子,而且当前的残局是红方正在将军,判断红方是否已经将死黑方
红方只有四种棋子,帅,车,炮,马,因此按照每个棋子的运算规则,即可判断出红方已经能吃到的位置
1。给棋子编码,炮是1,马是2,车是3,因为在对将的时候帅的作用和车是一样的,因此把帅也编成3号,按照车处理
2.这中间使用两个棋盘来记录,mp是残局时每个棋子的位置,an记录判断后红方能够吃到的位置,0代表不能吃到,-1表示能吃到。
之所以设置两个棋盘是因为,不能采用覆盖写的方式,因为如果覆盖写,在计算红方能吃到的位置的时候,就可能覆盖红方棋子。
3.中间容易出现错误的地方在于边界的判断,尤其是黑将在移动位置的时候可能会吃掉红方棋子,
因此在判断红方棋子能吃到的位置的时候,要考虑到红方能够吃到的红方自己的第一个棋子,这就是边界情况
 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<utility>
#include<unordered_set>
#include<unordered_map>
#include<string.h>
using namespace std;
 
 
 
 
int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int hou[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,-2},{2,-1},{2,1},{1,2}};
int leg[8][2]={{0,-1},{-1,0},{-1,0},{0,1},{0,-1},{1,0},{1,0},{0,1}};
int mp[11][10],an[11][10];
 
 
int check(int x,int y){return x>0&&x<11&&y>0&&y<10;}
void doH(int x,int y){
    for(int i=0;i<8;++i){
        int hx=x+hou[i][0],hy=y+hou[i][1];
        int lx=x+leg[i][0],ly=y+leg[i][1];
        if(check(lx,ly)&&mp[lx][ly]==0&&check(hx,hy))an[hx][hy]=-1;
    }
}
void doR(int x,int y){
    for(int i=x-1;i>0;--i){
        if(check(i,y)){
            an[i][y]=-1;
            if(mp[i][y]!=0)break;//这句代码作用就是判断红方棋子刚好吃到红方棋子的位置
        }
    }
    for(int i=x+1;i<11;++i){
        if(check(i,y)){
            an[i][y]=-1;
            if(mp[i][y]!=0)break;
        }
    }
    for(int i=y-1;i>0;--i){
        if(check(x,i)){
            an[x][i]=-1;
            if(mp[x][i]!=0)break;
        }
    }
    for(int i=y+1;i<10;++i){
        if(check(x,i)){
            an[x][i]=-1;
            if(mp[x][i]!=0)break;
        }
    }
}
void doC(int x,int y){
    int c;
    c=x-1;while(check(c,y)&&mp[c][y]==0)--c;
    for(int i=c-1;i>0;--i){
        if(check(i,y)){
            an[i][y]=-1;
            if(mp[i][y]!=0)break;
        }
    }
    c=x+1;while(check(c,y)&&mp[c][y]==0)++c;
    for(int i=c+1;i<11;++i){
        if(check(i,y)){
            an[i][y]=-1;
            if(mp[i][y]!=0)break;
        }
    }
    c=y-1;while(check(x,c)&&mp[x][c]==0)--c;
    for(int i=c-1;i>0;--i){
        if(check(x,i)){
            an[x][i]=-1;
            if(mp[x][i]!=0)break;
        }
    }
    c=y+1;while(check(x,c)&&mp[x][c]==0)++c;
    for(int i=c+1;i<10;++i){
        if(check(x,i)){
            an[x][i]=-1;
            if(mp[x][i]!=0)break;
        }
    }
}
 
void printm(){
    printf("Now chese is\n");
    for(int i=1;i<11;++i){
        for(int j=1;j<10;++j)printf("%3d",an[i][j]);
        printf("\n");
    }
}
 
int main()
{
    int N,px,py,x,y;
    char s[5];
    while(scanf("%d%d%d",&N,&px,&py)==3&&N){
        memset(mp,0,sizeof(mp));
        memset(an,0,sizeof(an));
        for(int i=0;i<N;++i){
            scanf("%s%d%d",s,&x,&y);
            if(s[0]=='C')mp[x][y]=1;
            if(s[0]=='H')mp[x][y]=2;
            if(s[0]=='R'||s[0]=='G')mp[x][y]=3;
        }
        //printm();
        for(int x=1;x<11;++x){
            for(int y=1;y<10;++y){
                if(mp[x][y]>0){
                    if(mp[x][y]==1)doC(x,y);
                    if(mp[x][y]==2)doH(x,y);
                    if(mp[x][y]==3)doR(x,y);
                    //printm();
                }
            }
        }
        int flag=1;
        for(int i=0;i<4;++i){
            x=px+d[i][0],y=py+d[i][1];
            if(x>0&&x<4&&y>3&&y<7&&an[x][y]==0){
                flag=0;
                break;
            }
        }
        printf("%s\n",flag==1?"YES":"NO");
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值