UVA - 1589 —Xiangqi (思路&&模拟)

版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/83754925

链接:

https://cn.vjudge.net/problem/UVA-1589

题意:

黑方只有一个帅,给出黑方帅的坐标,红方可能有车/炮和马,问当前黑方是否被将死。

思路:

见代码

代码目前是错的,但思路正确,有时间再改

#include <bits/stdc++.h>
using namespace std;
typedef struct L
{
    int a,b;
};
L General;
L Chariot[2];
L Horse[2];
L Cannon[2];
int i1,i2,i3;
int Qipan[11][10];
int n,x,y;
int tempx,tempy;
char type[10];
int flag;
int checkGenerals(int x,int y)//判断两个将是否直面
{
    if(General.b == y)//首先纵坐标必须一样
    {
        int Flag = 0;
        for(int i = x + 1; i < General.a; i++)
        {
            if(Qipan[i][y])//如果连线上有棋子,那么就不是直面
                return 0;
        }
        return 1;
    }
    return 0;
}
int checkChariot(int x1,int y1,int x2,int y2)//车
{
    //返回0 代表黑帅不会被将死 1 反之
    int Flag = 0;
    int xj1,yj1,xj2,yj2;
    xj1 = x1 < x2? x1 : x2;
    xj2 = x1 > x2? x1 : x2;
    yj1 = y1 < y2? y1 : y2;
    yj2 = y1 > y2? y1 : y2;
    //如果一样,说明这次移动,黑帅吃掉了这个车
    if(x1 == x2 && y1 == y2)
    {
        return 0;
    }
    if(x1 == x2)
    {
        Flag = 0;
        for(int j = yj1 + 1; j < yj2 ; j++)
            if(Qipan[x1][j])
                Flag = 1;
        if(flag == 0) return  1;
    }
    if(y1 == y2)
    {
        Flag = 0;
        for(int i = xj1 + 1; i < xj2 ; i++)
            if(Qipan[i][y1])
                Flag = 1;
        if(flag == 0)
            return 1;
    }
    return 0;
}
int checkHorse(int x1,int y1,int x2,int y2)//ma
{
    //一个马可以八方向移动,但要判断蹩马腿的情况
    if(x1+1==x2&&y1+2==y2)
        if(Qipan[x1][y1+1]==0)
            return 1;
    if(x1+1==x2&&y1-2==y2)
        if(Qipan[x1][y1-1]==0)
            return 1;
    if(x1-1==x2&&y1+2==y2)
        if(Qipan[x1][y1+1]==0)
            return 1;
    if(x1-1==x2&&y1-2==y2)
        if(Qipan[x1][y1-1]==0)
            return 1;
    if(x1+2==x2&&y1+1==y2)
        if(Qipan[x1+1][y1]==0)
            return 1;
    if(x1+2==x2&&y1-1==y2)
        if(Qipan[x1+1][y1]==0)
            return 1;
    if(x1-2==x2&&y1+1==y2)
        if(Qipan[x1-1][y1]==0)
            return 1;
    if(x1-2==x2&&y1-1==y2)
        if(Qipan[x1-1][y1]==0)
            return 1;
    return 0;
}
int checkCannon(int x1,int y1,int x2,int y2)//pao
{
    int Flag=0;
    int xj1,yj1,xj2,yj2;
    xj1=x1<x2?x1:x2;
    xj2=x1>x2?x1:x2;
    yj1=y1<y2?y1:y2;
    yj2=y1>y2?y1:y2;
    if(x1==x2&&y1==y2) return 0;//判断炮是否直接被吃掉
    if(x1==x2)
    {
        for(int j=yj1+1;j<yj2;j++)
            if(Qipan[x1][j]) Flag++;
        if(Flag==1) return 1;//中间只有一个棋子
    }
    if(y1==y2)
    {
        for(int i=xj1+1;i<xj2;i++)
            if(Qipan[i][y1]) Flag++;
        if(Flag==1) return 1;//中间只有一个棋子
    }
    return 0;
}
int checkPoint(int x,int y)//只要黑帅有1种可能被吃,这种移动就不可行,返回0
{
    //黑帅被将死checkpoint就返回0
    if(checkGenerals(x,y)) return 0;
    for(int i = 0; i < i1; i++)
    {
        if(checkChariot(Chariot[i].a,Chariot[i].b,x,y))
            return 0;
    }
    for(int i = 0; i < i2; i++)
    {
        if(checkHorse(Horse[i].a,Horse[i].b,x,y))
            return 0;
    }
    for(int i = 0; i < i3; i ++)
    {
        if(checkCannon(Cannon[i].a,Cannon[i].b,x,y))
            return 0;
    }
    return 1;//没有将死返回1
}
int main()
{
    while(cin>>n>>x>>y && n)
    {
        memset(Qipan,0,sizeof Qipan);//有棋子是1,无棋子是2
        Qipan[x][y] = 1;
        flag = 0;
        i1 = i2 = i3 = 0;
        for(int i = 0; i < n; i++)
        {
            cin>>type>>tempx>>tempy;
            Qipan[tempx][tempy] = 1;
            if(type[0] = 'G')//帅
            {
                General.a = tempx;
                General.b = tempy;
            }
            else if(type[0] = 'R')//车
            {
                Chariot[i1].a = tempx;
                Chariot[i1++].b = tempy;
            }
            else if(type[0] = 'H')//ma
            {
                Horse[i2].a = tempx;
                Horse[i2++].b = tempy;
            }
            else if(type[0] = 'C')//pao
            {
                Cannon[i3].a = tempx;
                Cannon[i3++].b = tempy;
            }
        }
        //首先判断帅与帅直接相对的情况
        if(checkGenerals(x,y))
        {
            cout<<"NO"<<endl;
            continue;
        }
        flag = 0;
        //之后对于黑帅的不同移动进行判断,只要有一种可行,就说明没将死。
        if(x + 1 < 4)//可以下移
        {
            Qipan[x][y] = 0;
            Qipan[x+1][y] = 1;
            if(checkPoint(x+1,y))
                flag = 1;
            Qipan[x][y]  = 1;
            Qipan[x+1][y] = 0;
        }
        if(flag)
        {
            cout<<"NO"<<endl;
            continue;
        }
        if(x-1 > 0)
        {
            Qipan[x][y] = 0;
            Qipan[x-1][y] = 1;
            if(checkPoint(x-1,y))
                flag  = 1;
            Qipan[x][y] = 1;
            Qipan[x-1][y] = 0;
        }

        if(flag)
        {
            cout<<"NO"<<endl;
            continue;
        }

        if(y+1 < 7)
        {
            Qipan[x][y] = 0;
            Qipan[x][y+1] = 1;
            if(checkPoint(x,y+1))
                flag = 1;
            Qipan[x][y] = 1;
            Qipan[x][y+1] = 0;
        }
        if(flag)
        {
            cout<<"NO"<<endl;
            continue;
        }
        if(y-1 > 3)
        {
            Qipan[x][y] = 0;
            Qipan[x][y-1] = 1;
            if(checkPoint(x,y-1))
                flag = 1;
            Qipan[x][y] = 1;
            Qipan[x][y-1] = 0;
        }
        if(flag)
        {
            cout<<"NO"<<endl;
        }
        cout<<"YES"<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Healer66/article/details/83754925
今日推荐