4-1 UVA 1589Xiangqi中国象棋

这个题,写完很久了,一直没发没记录,今天补上。

这个题自己真是错了不知多少遍了,数不清了,

换了个思路就AC了

整体思路:

用二维数组做棋盘,把红棋能吃的全都记录下来,让黑将一个一个走,看看走后是不是在记录范围内,发现一个不在在的话,就直接输出NO,

注意刚开始会有飞将的可能:

#include<stdio.h>
#define MAX 15
#include<string.h>
const int dx[] = {0,0,-1,1};
const int dy[] = {1,-1,0,0};
const int dx1[] = {1,-1,-2,-2,-1,1,2,2};
const int dy1[] = {2,2,1,-1,-2,-2,-1,1};
const int dx2[] = {0,0,-1,-1,0,0,1,1};
const int dy2[] = {1,1,0,0,-1,-1,0,0};
int flag[MAX][MAX];
struct re
{
    char type[MAX];
    int x,y;
} red[MAX];
int judge(int x,int y,int way)
{
    if (way == 1)
    {
        if (y >= 4 && y<= 6 && x >= 1 && x <= 3)return 1;
        return 0;
    }
    else
    {
        if (x >= 1 && x <= 10 && y >= 1 && y <= 9)return 1;
        return 0;
    }
}
void Horse(int red_num)
{
    int x0 = red[red_num].x;
    int y0 = red[red_num].y,i;
    for (i = 0; i < 8; i++)
    {
        int x1 = x0+dx1[i];
        int y1 = y0+dy1[i];
        int x2 = x0+dx2[i];
        int y2 = y0+dy2[i];
        if (flag[x2][y2] != 2 && judge(x1,y1,2))
            flag[x1][y1] = 1;
    }
}
void Chariot(int red_num)
{
    int i,x = red[red_num].x,y = red[red_num].y;
    for (i = y + 1; i < 10; i++)
    {

        if (flag[x][i] == 2)break;
        flag[x][i] = 1;
    }
    for (i = y - 1; i > 0; i--)
    {

        if (flag[x][i] == 2)break;
        flag[x][i] = 1;
    }
    for (i = x + 1; i < 11; i++)
    {

        if (flag[i][y] == 2)break;
        flag[i][y] = 1;
    }
    for (i = x - 1; i > 0; i--)
    {
        if (flag[i][y] == 2)break;
        flag[i][y] = 1;
    }
}
void Cannon(int red_num)
{
    int j,i,x = red[red_num].x,y = red[red_num].y;
    for (i = x - 1; i > 0; i--)
        if (flag[i][y] == 2)break;
    if (i != 1)
    {
        for (j = i - 1; j > 0; j--)
        {

            if (flag[j][y] == 2)break;
            flag[j][y] = 1;
        }
    }
    for (i = x + 1; i < 11; i++)
        if (flag[i][y] == 2)break;
    if (i != 10)
    {
        for (j = i + 1; j < 11; j++)
        {

            if (flag[j][y] == 2)break;
            flag[j][y] = 1;
        }
    }
    for (i = y + 1; i < 10; i++)
        if (flag[x][i] == 2)break;
    if (i != 9)
    {
        for (j = i + 1; j < 10; j++)
        {

            if (flag[x][j] == 2)break;
            flag[x][j] = 1;
        }
    }
    for (i = y - 1; i > 0; i--)
        if (flag[x][i] == 2)break;
    if (i != 1)
    {
        for (j = i - 1; j > 0; j--)
        {

            if (flag[x][j] == 2)break;
            flag[x][j] = 1;
        }
    }
}
void reset(int N)
{
    int i;
    memset(flag,0,sizeof(flag));

    for (i = 1; i <= N; i++)
    {
        int r_x = red[i].x;
        int r_y = red[i].y;
        flag[r_x][r_y] = 2;
    }
}
void again(int N)
{
    int i;
    for (i = 1; i <= N; i++)
    {
        char ch = red[i].type[0];
        if (ch == 'G' || ch == 'R')Chariot(i);
        if (ch == 'H')Horse(i);
        if (ch == 'C')Cannon(i);
    }
}
int main()
{
    char type[MAX];
    int N,b_x,b_y,r_x,r_y;
    int i,life = 0,j;
    while(scanf("%d%d%d",&N,&b_x,&b_y) && N)
    {
        memset(flag,0,sizeof(flag));
        for (i = 1; i <= N; i++)
        {
            scanf("%s%d%d",type,&r_x,&r_y);
            flag[r_x][r_y] = 2;
            red[i].x = r_x;
            red[i].y = r_y;
            red[i].type[0] = type[0];
        }
        for (j = 1; j <= N; j++)
            if (red[j].type[0] == 'G')break;
        life = 0;
        if (red[j].y == b_y)
        {
            for (i = red[j].x - 1; i > b_x; i--)
                if (flag[i][b_y] == 2)life = 1;
            if (life != 1)
            {
                printf("NO\n");
                continue;
            }
        }
         life = 0;
        for (i = 0; i < 4; i++)
        {
            reset(N);
            again(N);
           int life3 = 0;
            int xx = b_x + dx[i];
            int yy = b_y + dy[i];
            if (flag[xx][yy] == 2 && judge(xx,yy,1))
            {
                flag[xx][yy] = 0;
                again(N);
            }
            if (flag[xx][yy] != 1 && judge(xx,yy,1))life = 1;
        }
        printf(life == 1 ? "NO\n":"YES\n");
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值