4-1 UVA 1589 Xiangqi中国将棋

4543 ワード

この問題は、長い間書き終わっていて、ずっと記録を出していないので、今日補充します.
この問題は自分が本当に何度も間違っていて、数え切れないほど、
考えを変えてACになった
全体的な考え方:
二次元配列で碁盤を作り、赤い碁が食べられるものを全部記録して、黒に1つずつ歩かせて、歩いた後に記録範囲内にあるかどうかを見て、1つがいないことを発見したら、直接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
"); 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
":"YES
"); } return 0; }