uva1589

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva1589相关的知识,希望对你有一定的参考价值。

/*
problem:
当前没有考虑到列,只考虑到了行
还有吃子的问题需要一并想一想
这个题AC真的花了好久。。。。。。。
总而言之:需要多跑几个样例吧。uva依赖百度没用,以上!
因为这个题,差点放弃all,嗯  再坚持坚持吧! AC好像会在最后变成全部的动力!
*/
#include<stdio.h>
#include<string.h>
#define maxn 10
int n=0,X=0,Y=0;
struct Qi
{
    char c;
    int x,y;
}qi[maxn];
/*
函数功能:
    检查当前马的周围是否有棋子,即该匹马是否被蹩
返回结果:
    1:被蹩
    0:无
*/
int if_biema(int xm,int ym,int dx,int dy)
{
    int x = xm + dx;
    int y = ym + dy;
    int i = 0;
    for(i=0; i<n; i++)
    {
        if(qi[i].x == x && qi[i].y == y)
            return 1;
    }
    return 0;
}
/*
函数功能:
    检查该棋子线上是否存在其他棋子,以及存在的个数
返回值:
    存在个数
*/
int check_lie(int x,int y,int bottom)
{
    int i;
    int count = 0;
    int small =  x<bottom?x:bottom;
    int big = x + bottom - small;
    for(i=0; i<n; i++)
    {
        if(qi[i].y == y && qi[i].x < big && qi[i].x > small )
            count++;
    }
    //printf("夹杂棋子数:%d 当前列:%d\n",count,x);
    return count;
}

int check_hang(int x,int y,int bottom)
{
    int i;
    int count = 0;
    int small = y<bottom?y:bottom;
    int big = y + bottom - small;
    for(i=0; i<n; i++)
    {
        if(qi[i].x == x && qi[i].y<big && qi[i].y >small)
            count++;
    }
    //printf("count %d行 x:%d y:%d\n",count,x,y);
    return count;

}
/*
函数功能:
    检查棋子是否对当前位置起到将军效果
返回结果:
    1:已将死
    0:未将死
*/
int if_over(int x,int y)
{
    int i,j,k;
    int flag1 = 0,flag2 = 0;
    for(i=0; i<n; i++)
    {
        switch(qi[i].c)
        {
            //共性特征:将,车要求该列无其他棋子;马另外讨论;炮同
            //遇到将的时候
            case ‘G‘:
            {

                if(qi[i].y == y &&  qi[i].x != x && (check_lie(qi[i].x,qi[i].y,x)==0))
                {
                    //printf("%d %d位置被老将将死\n",x,y);
                    if(x == X && y == Y)
                        flag2 = 1;
                    else
                        flag1 = 1;

                }
                //printf("%d",check_lie(qi[i].x));
                break;
            }
            //遇到车的时候,需要考虑该直线上是否存在其他棋子,还需要考虑另外一种情况
            case ‘R‘:
            {
                if(qi[i].y == y  && qi[i].x != x&& (check_lie(qi[i].x,qi[i].y,x) == 0) )
                {
                    //printf("%d %d位置被车将死\n",x,y);
                    flag1 = 1;
                }
                else if(qi[i].x == x  && qi[i].y != y && check_hang(qi[i].x,qi[i].y,y) == 0)
                {
                    //printf("%d %d位置被车将死\n",x,y);
                    flag1 =  1;
                }
                break;

            }
            //遇到炮的时候,需要考虑直线上是否有支架,且支架唯一
            case ‘C‘:
            {
                if(qi[i].y == y  && qi[i].x != x && (check_lie(qi[i].x,qi[i].y,x) == 1))
                {
                    //printf("%d %d位置被炮将死\n",x,y);
                    flag1 =  1;
                }
                else if(qi[i].x == x && qi[i].y != y && (check_hang(qi[i].x,qi[i].y,y) == 1))
                {
                    flag1 =  1;
                }


                break;
            }
            //遇到马的时候,需要考虑三个方向是否蹩脚
            case ‘H‘:
            {
                if(if_biema(qi[i].x,qi[i].y,0,-1 ) == 0)
                {
                    if(qi[i].y-2 == y && (qi[i].x-1 == x || qi[i].x+1 == x))
                    {
                        //printf("%d %d位置被马将死\n",x,y);
                        flag1 = 1;
                    }

                }
                if(if_biema(qi[i].x,qi[i].y,-1,0) == 0)
                {
                    if((qi[i].y-1 == y || qi[i].y+1 == y) && qi[i].x - 2 == x)
                    {
                        //printf("%d %d位置被马将死\n",x,y);
                        flag1 =  1;
                    }
                }
                if(if_biema(qi[i].x,qi[i].y,0,1) == 0)
                {
                    if(qi[i].y+2 == y &&(qi[i].x-1 == x || qi[i].x+1 == x))
                    {
                        //printf("%d %d位置被马将死\n",x,y);
                        flag1 =  1;
                    }
                }
                if(if_biema(qi[i].x,qi[i].y,1,0) == 0)
                {
                    if((qi[i].y-1 == y || qi[i].y+1 == y)&& qi[i].x+2 == x)
                    {
                        //printf("%d %d位置被马将死\n",x,y);
                        flag1 =  1;

                    }
                    break;
                }
            }
        }
    }
    if(flag2 == 1)
        return 2;
    else if(flag1 == 1)
        return 1;
    else
        return 0;
}
/*
函数功能:
    检查老将以及老将四处移动后的位置是否安全(确定四个,因为老将可以吃掉别的)
返回值:
    1:存在安全位置,未将死
    0:不存在安全位置,已将死
*/
int move()
{
    int i;
    if(if_over(X,Y) == 0 || if_over(X,Y) == 2)
        return 1;
    else
    {
        int dx=0,dy=0;
        for(i=0; i<4; i++)
        {
            switch(i)
            {
                case 0: dx = X-1; dy = Y; break;
                case 1: dx = X+1; dy = Y; break;
                case 2: dx = X; dy = Y-1; break;
                case 3: dx = X; dy = Y+1; break;
            }
            //printf("%d %d位置检测中\n",dx,dy);
            if(dx>=1 && dx<=3 && dy>=4 && dy<=6)
            {
                //printf("%当前位置:x:%d y:%d 结果%d \n",dx,dy,if_over(dx,dy));
                if(if_over(dx,dy) == 0 )
                    return 1;
            }
            //else
                //printf("该位置不存在\n");
            //printf("%d %d位置已将死\n",dx,dy);
        }
    }
    return 0;
}
int main(void)
{
    while(scanf("%d %d %d",&n,&X,&Y)==3 && n+X+Y != 0)
    {
        int i;
        for(i=0; i<n; i++)
        {
            scanf("\n%c %d %d",&qi[i].c,&qi[i].x,&qi[i].y);
            //printf("%c %d %d\n",qi[i].c,qi[i].x,qi[i].y);
        }

        if(move() == 0)
            printf("YES\n");
        else
            printf("NO\n");

    }
    return 0;
}

以上是关于uva1589的主要内容,如果未能解决你的问题,请参考以下文章

uva1589

Xiangqi UVa1589(多次WA)

UVA 1589 象棋

UVA-1589 象棋(模拟)

uva1589(象棋)。

UVA1589 Xiangqi(挖坑待填)