4-1 UVA 1589 Xiangqi中国将棋
この問題は、長い間書き終わっていて、ずっと記録を出していないので、今日補充します.
この問題は自分が本当に何度も間違っていて、数え切れないほど、
考えを変えてACになった
全体的な考え方:
二次元配列で碁盤を作り、赤い碁が食べられるものを全部記録して、黒に1つずつ歩かせて、歩いた後に記録範囲内にあるかどうかを見て、1つがいないことを発見したら、直接NOを出力します.
最初は飛将の可能性に注意してください.
この問題は自分が本当に何度も間違っていて、数え切れないほど、
考えを変えて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;
}