1. 程式人生 > >UVA - 1589 —Xiangqi (思路&&模擬)

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

連結:

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;
}