UVA 1589 Xiangqi

题意:黑方场上只有一个将 红方可能有车马炮帅4种棋 且现在已经将军 判断是否将死 

其实并不算很大的模拟 只是题意有些复杂 

因为棋盘的范围很小 所以可以用一个二维的字符数组模拟棋盘 然后大体可以分2种模拟方法

一种是判断将周围的4个位置是否可行 即由将去找车马炮帅

另一种是把每一个红方棋子的攻击范围标记 再判断4个位置是否被标记 即由车马炮帅去找将

其实都差不多 下面代码采用前一种 对于某个位置是否可行 车炮帅可以一起判断 马要单独判断一下蹩腿的问题

本题要注意将可以吃红方的棋子  还有初始明将的问题(输出NO) 以及将不能出那9个格子 其他细节写在代码注释中了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
const int mod=1000000007;
const int maxn=1e5+5;
const int inf=1e9;
char mapp[100][100];
//G帅 R车 H马 炮C
int x,y,n;
bool mingjiang(){ //判断是否明将
    for(int i=x+1;i<50;i++){
        if(i>10) return 0;
        if(mapp[i][y]=='G') return 1;
        if(mapp[i][y]) return 0;
    }
}
bool inmapp(int x,int y){//在地图内
    if(x<1||x>10||y<1||y>9)return 0;
    return 1;
}
bool zhixian(int x,int y,int dx,int dy)// 在某一行/列 找车炮帅 1表示找到了
{
    int cnt=0;
    for(int i=0;i<=20;i++)
    {
        x+=dx; y+=dy;
        if(!inmapp(x,y))return 0;
        if(cnt==0&&(mapp[x][y]=='G'||mapp[x][y]=='R')) return 1;//找到车帅 没隔子
        if(cnt==1&&mapp[x][y]=='C') return 1;//找到炮 隔一个
        if(mapp[x][y]) cnt++;
    }
}
int fx[4][2]={-1,0, 1,0, 0,1, 0,-1};//蹩马腿的4个方向
int fx4[4][2]={-1,-1, 1,1, -1,1, 1,-1};//蹩马腿的4个方向
int ma[4][2][2]={-2,-1,-1,-2,  2,1,1,2, -1,2,-2,1, 1,-2, 2,-1};//马的8个方向
bool pd(int x,int y)//能否找到杀死它的单位
{
    if(x<1||x>3||y<4||y>6) return 1;//从9格中出来了
    if(zhixian(x,y,0,1)||zhixian(x,y,0,-1)||zhixian(x,y,1,0)||zhixian(x,y,-1,0)) return 1;
    for(int i=0;i<4;i++) //找马
    {
        int xx=fx4[i][0]+x,yy=fx4[i][1]+y;
        if(inmapp(xx,yy)&&mapp[xx][yy]==0)
        {
          int x2=x+ma[i][0][0],y2=y+ma[i][0][1];
          if(inmapp(x2,y2)&&mapp[x2][y2]=='H') return 1;
           x2=x+ma[i][1][0],y2=y+ma[i][1][1];
          if(inmapp(x2,y2)&&mapp[x2][y2]=='H') return 1;
        }
    }
    return 0;
}
int main()
{
    while(~scanf("%d%d%d",&n,&x,&y),n||x||y)
    {
        memset(mapp,0,sizeof(mapp));
        for(int i=0;i<n;i++)
        {
            int xx,yy;
            char zz[5];
            scanf("%s%d%d",zz,&xx,&yy);
            mapp[xx][yy]=zz[0];
        }
        if(mingjiang()){
             puts("NO");
             continue;
        }
        int flag=1;
        for(int i=0;i<4;i++)
            if(!pd(x+fx[i][0],y+fx[i][1]))//找不到就将不死了
            {
                flag=0;
                break;
            }
        if(flag) puts("YES");
        else puts("NO");
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值