Poj-4001 Xiangqi

徐州矿大冬令营第一天训练题,写的简直要吐血,一开始写了半下午,晚上看了题解找bug找了两个多小时…最后竟然多写了一个=…啊啊啊啊啊啊!!!

[题解]: 首先,判断黑方的将是不是可以直接以“飞将”的方式将死红方。如果黑方不能直接将 死红方,则对黑方的将下一步可以走到的交叉点,分析在这个交叉点是否会被红方吃掉:先 判断这个交叉点的四个方向上有没有红方的車;如果不存在車的威胁,则继续判断是否存在 红方的炮的威胁;如果不存在炮的威胁,则继续判断是否存在红方的马的威胁,当然还要考 虑马是否存在“蹩马腿”的状况。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,x1,y1;
char mp[22][22];
int dir[4][2]={1,0,-1,0,0,1,0,-1}; // 上下左右四个方向
int fx[8][2]={1,2,1,-2,2,1,2,-1,-1,2,-1,-2,-2,1,-2,1};  // 马的位置
int bx[8][2]={1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,-1,-1}; ; // 绊马蹄位置

bool check1(int x,int y){ // 红方和黑方的将面对面
    for(int i=x+1;i<=10;i++){
        if(mp[i][y]=='\0')continue;
        if(mp[i][y]!='G')return false;
        return true;
    }
    return false;
}

bool check(int x,int y){ // 判断黑方的将是否能被将死
    if(check1(x,y))return false;
    for(int i=0;i<4;i++){
        int h=x+dir[i][0];
        int l=y+dir[i][1];
        while(h>=1&&h<=10&&l>=1&&l<=9){
            if(mp[h][l]=='\0'){
                h+=dir[i][0];
                l+=dir[i][1];
                continue;
            }
            if(mp[h][l]=='R')return false; // 判車
            int hh=h+dir[i][0];
            int ll=l+dir[i][1];
            while(hh>=1&&hh<=10&&ll>=1&&ll<=9){
                if(mp[hh][ll]=='\0'){
                    hh+=dir[i][0];
                    ll+=dir[i][1];
                    continue;
                }
                if(mp[hh][ll]=='C')return false; // 判炮
                break;
            }
            break;
        }
    }
    for(int i=0;i<8;i++){ // 判马
       int h=x+fx[i][0],l=y+fx[i][1];
       int hh=x+bx[i][0],ll=y+bx[i][1];
       if(h>=1&&h<=10&&l>=1&&l<=9&&mp[h][l]=='H'&&mp[hh][ll]=='\0')
        return false;
    }
    return true;
}

int main()
{
    while(~scanf("%d%d%d",&n,&x1,&y1)&&(n+x1+y1)){
        memset(mp,0,sizeof(mp));
        char ch[5];
        int a,b;
        for(int i=1;i<=n;i++){
            scanf("%s%d%d",ch,&a,&b);
            mp[a][b]=ch[0];
        }
        if(check1(x1,y1)){ // 黑方飞将获胜(黑方不能被将死)
            printf("NO\n");
            continue;
        }
        bool flag=true;
        for(int i=0;i<4;i++){ //枚举黑方的将走的四个位置
            int x=x1+dir[i][0];
            int y=y1+dir[i][1];
//            cout<<x1<<' '<<y1<<endl;
            if(x>=1&&x<=3&&y>=4&&y<=6){
                char cc=mp[x][y];
                mp[x][y]='\0';
                if(check(x,y)){
                    flag=false;
//                    cout<<x<<' '<<y<<endl;
                    printf("NO\n");
                    break;
                }
                mp[x][y]=cc;
            }
        }
        if(flag)printf("YES\n");
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值