象棋

Problem Description
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”.
象棋_第1张图片
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”.
象棋_第2张图片
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”.
 
Input
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.
 
Output
For each test case, if the situation is checkmate, output a single word ‘YES’, otherwise output the word ‘NO’.
 
Sample Input
2 1 4
G 10 5
R 6 4
 
3 1 5
H 4 5
G 10 5
C 7 5
 
0 0 0
 
Sample Output
YES NO
Hint
象棋_第3张图片
In the first situation, the black general is checked by chariot and “flying general”. In the second situation, the black general can move to (1, 4) or (1, 6) to stop check. See the figure above.
 
 
情况很多!加油!!!
定义一个新的棋盘所有元素为0,将红方可以到达的地方设定为1,然后若黑方走到的地方元素都为1,则黑方失败。
WA代码
  1 #include
  2 #include
  3 #include<string.h>
  4 using namespace std;
  5 char chu[12][11];
  6 int hong[15][15];       //初始棋盘为chu,红方棋子能到达的地方为hong
  7 int x[8],y[8];
  8 void GorR(int x,int y)
  9 {
 10     for(int i=y+1;i<10;i++){
 11         if(chu[x][i]!='0')break;
 12         hong[x][i]=1;
 13     }
 14     for(int i=y-1;i>0;i--){
 15         if(chu[x][i]!='0')break;
 16         hong[x][i]=1;
 17     }
 18     for(int j=x+1;j<11;j++){
 19         if(chu[j][y]!='0')break;
 20         hong[j][y]=1;
 21     }
 22     for(int j=x-1;j>0;j--){
 23         if(chu[j][y]!='0')break;
 24         hong[j][y]=1;
 25     }
 26 }
 27 
 28 
 29 void C(int x,int y)
 30 {
 31     bool flag=false;
 32     for(int i=x-1;i>0;i--){
 33         if(flag==false){
 34             if(chu[i][y]!='0')flag=true;
 35         }
 36         else{
 37             if(chu[i][y]=='0'||chu[i][y]=='J')hong[i][y]=1;
 38             else flag=false;
 39         }
 40     }
 41     flag=false;
 42     for(int i=x+1;i<11;i++){
 43         if(flag==false){
 44             if(chu[i][y]!='0')flag=true;
 45         }
 46         else{
 47             if(chu[i][y]=='0'||chu[i][y]=='J')hong[i][y]=1;
 48             else flag=false;
 49         }
 50     }
 51     flag=false;
 52     for(int i=y-1;i>0;i--){
 53         if(flag==false){
 54             if(chu[x][i]!='0')flag=true;
 55         }
 56         else{
 57             if(chu[x][i]=='0'||chu[i][y]=='J')hong[x][i]=1;
 58             else flag=false;
 59         }
 60     }
 61     flag=false;
 62     for(int i=y+1;i<10;i++){
 63         if(flag==false){
 64             if(chu[x][i]!='0')flag=true;
 65         }
 66         else{
 67             if(chu[x][i]=='0'||chu[i][y]=='J')hong[x][i]=1;
 68             else flag=false;
 69         }
 70     }
 71 }
 72 
 73 void H(int x,int y)
 74 {
 75     cout<1<<" "<" "<1][y]<<endl;
 76     if(chu[x-1][y]=='0'){
 77         hong[x-2][y-1]=1;
 78         hong[x-2][y+1]=1;
 79     }
 80     if(chu[x+1][y]=='0'){
 81         hong[x+2][y-1]=1;
 82         hong[x+2][y+1]=1;
 83     }
 84     if(chu[x][y-1]=='0'){
 85         hong[x-1][y-2]=1;
 86         hong[x+1][y-2]=1;
 87     }
 88     if(chu[x][y+1]=='0'){
 89         hong[x-1][y+2]=1;
 90         hong[x+1][y+2]=1;
 91     }
 92 }
 93 
 94 void hong_get(int n)
 95 {
 96     for(int i=0;i){
 97         if(chu[x[i]][y[i]]=='H')H(x[i],y[i]);
 98         if(chu[x[i]][y[i]]=='G'||chu[x[i]][y[i]]=='R')GorR(x[i],y[i]);
 99         if(chu[x[i]][y[i]]=='C')C(x[i],y[i]);
100     }
101 }
102 
103 int J_get(int x,int y)
104 {
105     if(x-1>0){
106         if(hong[x-1][y]==0)return 0;
107     }
108     if(x+1<4){
109         if(hong[x+1][y]==0)return 0;
110     }
111     if(y-1>3){
112         if(hong[x][y-1]==0)return 0;
113     }
114     if(y+1<7){
115         if(hong[x][y+1]==0)return 0;
116     }
117     return 1;
118 }
119 
120 int main()
121 {
122     int n,x0,y0,x1,y1,result;                   //n个红方和一个黑方的位置
123     while(scanf("%d%d%d",&n,&x0,&y0)&&n!=0){
124         memset(chu,'0',sizeof(chu));
125         memset(hong,0,sizeof(hong));
126         chu[x0][y0]='J';                //黑方的将存为J
127         for(int i=0;i){
128             char ch;
129             cin>>ch>>x[i]>>y[i];        //G为帅,R为车,H为马,C为炮
130             chu[x[i]][y[i]]=ch;
131         }
132         /*for(int j=1;j<11;j++){
133             for(int i=1;i<10;i++)cout<134             cout<135         }*/
136         hong_get(n);
137         result=J_get(x0,y0);
138         /*cout<<"***"<139         for(int j=1;j<11;j++){
140             for(int i=1;i<10;i++)cout<141             cout<142         }*/
143             if(result==0)cout<<"NO"<<endl;
144             else cout<<"YES"<<endl;
145     }
146     //system("pause");
147     return 0;
148 }

 

思路关键:::要想到设定一个新棋盘来标志红方可以走到的地方!

以上代码细节错误很多!!

AC代码以下

  1 #include
  2 #include
  3 #include<string.h>
  4 using namespace std;
  5 char chu[12][11];
  6 int hong[15][15];       //初始棋盘为chu,红方棋子能到达的地方为hong
  7 int x[8],y[8];
  8  
  9 void GorR(int x,int y)
 10 {
 11     for(int i=y+1;i<10;i++){
 12         hong[x][i]=1;
 13         if(chu[x][i]!='0'&&chu[x][i]!='J')break;
 14         
 15     }
 16     for(int i=y-1;i>0;i--){
 17         hong[x][i]=1;
 18         if(chu[x][i]!='0'&&chu[x][i]!='J')break;
 19         
 20     }
 21     for(int j=x+1;j<11;j++){
 22         hong[j][y]=1;
 23         if(chu[j][y]!='0'&&chu[x][j]!='J')break;
 24         
 25     }
 26     for(int j=x-1;j>0;j--){
 27         hong[j][y]=1;
 28         if(chu[j][y]!='0'&&chu[x][j]!='J')break;
 29         
 30     }
 31 }
 32        
 33 void C(int x,int y)
 34 {
 35     bool flag=false;
 36      if(y>=4&&y<=6&&x==1)  
 37         if(chu[2][y]!='0'&&chu[2][y]!='J') hong[3][y]=1;  
 38     for(int i=x-1;i>0;i--){
 39         if(flag==false){
 40             if(chu[i][y]=='J')return;
 41             if(chu[i][y]!='0')flag=true;
 42         }
 43         else{
 44             if(chu[i][y]=='0'||chu[i][y]=='J')hong[i][y]=1;
 45             else break;
 46         }
 47     }
 48       flag=false;
 49       for(int i=x+1;i<11;i++){
 50           if(flag==false){
 51               if(chu[i][y]=='J')return;
 52               if(chu[i][y]!='0')flag=true;
 53           }
 54           else{
 55               if(chu[i][y]=='0'||chu[i][y]=='J')hong[i][y]=1;
 56               else break;
 57           }
 58       }
 59     flag=false;
 60     for(int i=y-1;i>0;i--){
 61         if(flag==false){
 62             if(chu[i][y]=='J')return;
 63             if(chu[x][i]!='0')flag=true;
 64         }
 65         else{
 66             if(chu[x][i]=='0'||chu[i][y]=='J')hong[x][i]=1;
 67             else break;
 68         }
 69     }
 70     flag=false;
 71     for(int i=y+1;i<10;i++){
 72         if(flag==false){
 73             if(chu[i][y]=='J')return;
 74             if(chu[x][i]!='0')flag=true;
 75         }
 76         else{
 77             if(chu[x][i]=='0'||chu[i][y]=='J')hong[x][i]=1;
 78             else break;
 79         }
 80     }
 81 }
 82 
 83 void H(int x,int y)
 84 {
 85     if(chu[x][y+1]=='0'&&y+2<=9&&x-1>=1)hong[x-1][y+2]=1;
 86     if(chu[x][y+1]=='0'&&y+2<=9&&x+1<11)hong[x+1][y+2]=1;
 87     if(chu[x][y-1]=='0'&&y-2>=1&&x-1>=1)hong[x-1][y-2]=1;
 88     if(chu[x][y-1]=='0'&&y-2>=1&&x+1<11)hong[x+1][y-2]=1;
 89     if(chu[x+1][y]=='0'&&y-1>=1&&x+2<11)hong[x+2][y-1]=1;
 90     if(chu[x+1][y]=='0'&&y+1<=9&&x+2<11)hong[x+2][y+1]=1;
 91     if(chu[x-1][y]=='0'&&y-1>=1&&x-2>=1)hong[x-2][y-1]=1;
 92     if(chu[x-1][y]=='0'&&y+1<=9&&x-2>=1)hong[x-2][y+1]=1;
 93 }
 94 
 95 void hong_get(int n)
 96 {
 97     for(int i=0;i){
 98         if(chu[x[i]][y[i]]=='H')H(x[i],y[i]);
 99         else if(chu[x[i]][y[i]]=='G'||chu[x[i]][y[i]]=='R')GorR(x[i],y[i]);
100         else if(chu[x[i]][y[i]]=='C')C(x[i],y[i]);
101     }
102 }
103 
104 int J_get(int x,int y)
105 {
106     if(x-1>0&&hong[x-1][y]==0)return 0;
107     if(x+1<4&&hong[x+1][y]==0)return 0;
108     if(y-1>3&&hong[x][y-1]==0)return 0;
109     if(y+1<7&&hong[x][y+1]==0)return 0;
110     return 1;
111 }
112 
113 int main()
114 {
115     int n,x0,y0,result;                   //n个红方和一个黑方的位置
116     while(scanf("%d%d%d",&n,&x0,&y0)&&n!=0){
117         memset(chu,'0',sizeof(chu));
118         memset(hong,0,sizeof(hong));
119         chu[x0][y0]='J';                //黑方的将存为J
120         for(int i=0;i){
121             char ch;
122             cin>>ch>>x[i]>>y[i];        //G为帅,R为车,H为马,C为炮
123             chu[x[i]][y[i]]=ch;
124         }
125           /* for(int j=1;j<11;j++){
126             for(int i=1;i<10;i++)cout<127              cout<128          }*/
129          hong_get(n);
130          result=J_get(x0,y0);
131          /*cout<<"***"<132          for(int j=1;j<11;j++){
133             for(int i=1;i<10;i++)cout<134              cout<135          }*/
136         if(result==0)cout<<"NO"<<endl;
137         else cout<<"YES"<<endl;
138     }
139 //system("pause");
140     return 0;
141 }

 

比较结果错误的代码 和 AC代码

Ⅰ  void GorR(int x,int y)

WA代码中,先判断条件chu[x][i]!='0'  ,若成立,退出循环,那么chu[x][i]这一项的hong未被变为1,而这一项被一个棋子占用,黑方的将根本无法到达,所以该项的hong也应该被设定为1。

 

Ⅱ void C(int x,int y)

首先,炮只能隔一个棋子吃对方的棋子,WA代码中将这个概念理解错误,使炮隔一个,三个,五个....棋子时都可以吃棋子,即代码中同一循环中flag变为true时,不应再将其还原为false,还原的话就实现了炮的“连吃”。

第二点,当炮与黑方的将之间无其他棋子时,就可直接退出炮函数,因为他两相邻,红方走一步不可能用炮打败黑方,因此添加代码  if(chu[i][y]=='J')return;

第三点,当炮的一方向已有一个棋子时即flag=true后继续向这一方向检索,若检索到的下一个棋子不是黑方的将,也可直接退出循环,同样红方走一步不可能用炮打败黑方,因此AC代码中添加  else break;

Ⅲ void H(int x,int y)

马的一侧被一个棋子挡住,不能向这一侧的两个位置走,而这两个位置是否在棋盘内是独立的关系,所以不能将两种情况用一个条件判断,将其分开写即可,各自的条件对应各自的操作。

 

 

细心细心细心!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1

 

 

你可能感兴趣的:(象棋)