Xiangqi is one of the most popular two-player board
games in China. The game represents a battle between two armies with the goal of
capturing the enemy’s “general” piece. In this problem, you are given a
situation of later stage in the game. Besides, the red side has already
“delivered a check”.
Your work is to check whether the situation is
“checkmate”.Now we introduce some basic rules of Xiangqi. Xiangqi is
played on a 10×9 board and the pieces are placed on the intersections (points).
The top left point is (1,1) and the bottom right point is (10,9). There are two
groups of pieces marked by black or red Chinese characters, belonging to the two
players separately. During the game, each player in turn moves one piece from
the point it occupies to another point. No two pieces can occupy the same point
at the same time. A piece can be moved onto a point occupied by an enemy piece,
in which case the enemy piece is "captured" and removed from the board. When the
general is in danger of being captured by the enemy player on the enemy player’s
next move, the enemy player is said to have
"delivered a check". If the
general‘s player can make no move to prevent the general‘s capture by next enemy
move, the situation is called
“checkmate”.
We only use 4 kinds of pieces
introducing as follows:
General: the generals can move and capture
one point either vertically or horizontally and cannot leave the
“
palace” unless the situation called “
flying general” (see the
figure above). “Flying general” means that one general can “fly” across the
board to capture the enemy general if they stand on the same line without
intervening pieces.
Chariot: the chariots can move and capture
vertically and horizontally by any distance, but may not jump over intervening
pieces
Cannon: the cannons move like the chariots,
horizontally and vertically, but capture by jumping
exactly one piece
(whether it is friendly or enemy) over to its target.
Horse: the horses
have 8 kinds of jumps to move and capture shown in the left figure. However, if
there is any pieces lying on a point away from the horse horizontally or
vertically it cannot move or capture in that direction (see the figure below),
which is called “
hobbling the horse’s leg”.
Now you are given a
situation only containing a black general, a red general and several red
chariots, cannons and horses, and the red side has delivered a check. Now it
turns to black side’s move. Your job is to determine that whether this situation
is “checkmate”.
The input contains no more than 40 test cases. For each
test case, the first line contains three integers representing the number of red
pieces N (2<=N<=7) and the position of the black general. The following n
lines contain details of N red pieces. For each line, there are a char and two
integers representing the type and position of the piece (type char ‘G’ for
general, ‘R’ for chariot, ‘H’ for horse and ‘C’ for cannon). We guarantee that
the situation is legal and the red side has delivered the check.
There is a
blank line between two test cases. The input ends by 0 0 0.
For each test case, if the situation is checkmate,
output a single word ‘YES’, otherwise output the word ‘NO’.
lcy | We have carefully selected several similar
problems for you:
4126 4125 4123 4122 4130
比赛时遇到的题,好心酸,不知道WA了多少次,最后改的情况也不很懂,个人觉得可以充当炮架子的棋子只有炮和马,因为我先统计的车和帅,假如出现车和帅,应该可以直接将军,就不需要后面的炮了,但是这样写会WA,直到改成所有棋子可以充当炮架子才过,心酸心酸~
解题思路:考虑将可以一步走到的所有点,判断每个点都否都有红方棋子可以走到,若是,则为将死,输出YES,不是,则将不死,输出NO。要考虑将移动时可能会直接吃掉一个红方棋子。不需要考虑棋局一开始红帅黑将碰面将军吃掉帅的这种情况。
题意:中国象棋,每个棋子的走法没变,第一排输入n,x,y,表示还有n个红方棋子,以及黑方将位置为(x,y),接下来n行输入,每行三个数,第一个为字母,G代表帅,R代表车,C代表炮,H代表马,第二三个数表示这个棋子的位置。判断黑方是否已经死棋(即下一次黑将无论走哪都会死,不可以不走!),是输出YES,不是输出NO。(黑方只剩下将,红方还可以存在帅,车,炮,马,不过最多只能有8个)
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 using namespace std;
6 int vis[15][15];
7 bool search(int a,int b) ///如果将军在此点会被攻击,返回0,否则返回1
8 {
9 int i,j,t;
10 if(a-2>0&&b-1>0&&vis[a-2][b-1]==5&&!vis[a-1][b-1]) return 0; ///先判断是否有能攻击这个地方的马,注意马不能撇脚
11 if(b-2>0&&a-1>0&&vis[a-1][b-2]==5&&!vis[a-1][b-1]) return 0;
12 if(a-2>0&&b+1<=9&&vis[a-2][b+1]==5&&!vis[a-1][b+1]) return 0;
13 if(b+2<=9&&a-1>0&&vis[a-1][b+2]==5&&!vis[a-1][b+1]) return 0;
14 if(a+2<=10&&b+1<=9&&vis[a+2][b+1]==5&&!vis[a+1][b+1]) return 0;
15 if(b-2>0&&a+1<=10&&vis[a+1][b-2]==5&&!vis[a+1][b-1]) return 0;
16 if(a+2<=10&&b-1>0&&vis[a+2][b-1]==5&&!vis[a+1][b-1]) return 0;
17 if(b+2<=9&&a+1<=10&&vis[a+1][b+2]==5&&!vis[a+1][b+1]) return 0;
18 t=0;
19 for(i=a-1; i>=1; i--) ///搜将军的上下左右的四个方向是否有可以攻击将军的棋子,
20 {
21 if(!t&&(vis[i][b]==3||vis[i][b]==2)) return 0; ///碰到车或者帅,可攻击此点
22
23 if(vis[i][b]==4&&t==1)return 0; ///碰到前方有炮架子的炮,
24 if(vis[i][b]!=0) t++; ///所有的棋可充当炮架子
25 }
26 t=0;
27 for(i=a+1; i<=10; i++)
28 {
29 if(!t&&(vis[i][b]==3||vis[i][b]==2)) return 0;
30
31 if(vis[i][b]==4&&t==1) return 0;
32 if(vis[i][b]!=0) t++;
33 }
34 t=0;
35 for(i=b-1; i>=1; i--)
36 {
37 if(!t&&(vis[a][i]==3||vis[a][i]==2)) return 0;
38
39 if(vis[a][i]==4&&t==1) return 0;
40 if(vis[a][i]!=0) t++;
41 }
42 t=0;
43 for(i=b+1; i<=9; i++)
44 {
45 if(!t&&(vis[a][i]==3||vis[a][i]==2)) return 0;
46
47 if(vis[a][i]==4&&t==1) return 0;
48 if(vis[a][i]!=0) t++;
49 }
50 return 1; ///将军在此点不会被攻击到,返回1
51 }
52 int main()
53 {
54 int n,xx,yy,i,j,aa,bb,x,y;
55 char c;
56 while(~scanf("%d%d%d",&n,&xx,&yy))
57 {
58 aa=0,bb=0;
59 if(n==0&&xx==0&&yy==0)
60 break;
61 memset(vis,0,sizeof(vis));
62 for(i=1; i<=n; i++)
63 {
64 // getchar();
65 // scanf("%c %d %d",&c,&x,&y);
66 cin>>c>>x>>y; ///scanf输入容易WA
67 //cout<<c<<endl;
68 if(c==‘G‘) ///直接用V的值记录棋子,初始为0,帅为2,车为3,炮为4,马为5
69 {
70 vis[x][y]=2;
71 aa=x,bb=y;
72 }
73 else if(c==‘R‘)
74 vis[x][y]=3;
75 else if(c==‘C‘)
76 vis[x][y]=4;
77 else if(c==‘H‘)
78 vis[x][y]=5;
79 }
80 int k;
81 /* if(aa!=0&&bb!=0)
82 if(yy==bb)
83 {
84 for(i=xx+1; i<aa; i++)
85 if(vis[i][bb]!=0)
86 break;
87 if(i==aa)
88 {
89 printf("NO\n");
90 continue;
91 }
92 }*/
93 if(xx+1<=3&&xx+1>=1) ///将军不能超出边界
94 {
95 k=search(xx+1,yy);
96 if(k) ///出现1,则将军起码有一个点安全,所以未将死,输出NO
97 {
98 printf("NO\n");
99 continue;
100 }
101 }
102
103 if(xx-1>=1&&xx-1<=3)
104 {
105 k=search(xx-1,yy);
106 if(k)
107 {
108 printf("NO\n");
109 continue;
110 }
111 }
112 if(yy+1<=6&&yy+1>=4)
113 {
114 k=search(xx,yy+1);
115 if(k)
116 {
117 printf("NO\n");
118 continue;
119 }
120 }
121 if(yy-1>=4&&yy-1<=6)
122 {
123 k=search(xx,yy-1);
124 if(k)
125 {
126 printf("NO\n");
127 continue;
128 }
129 }
130 printf("YES\n"); ///没有出现为将死的情况,输出YES
131 }
132 return 0;
133 }