zoukankan      html  css  js  c++  java
  • 象棋

    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”.
    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”.
     
    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
    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<iostream>
      2 #include<cstdio>
      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<<x-1<<" "<<y<<" "<<chu[x-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<n;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<n;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<<chu[j][i]<<" ";
    134             cout<<endl;
    135         }*/
    136         hong_get(n);
    137         result=J_get(x0,y0);
    138         /*cout<<"***"<<endl<<endl;
    139         for(int j=1;j<11;j++){
    140             for(int i=1;i<10;i++)cout<<hong[j][i]<<" ";
    141             cout<<endl;
    142         }*/
    143             if(result==0)cout<<"NO"<<endl;
    144             else cout<<"YES"<<endl;
    145     }
    146     //system("pause");
    147     return 0;
    148 }

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

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

    AC代码以下

      1 #include<iostream>
      2 #include<cstdio>
      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<n;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<n;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<<chu[j][i]<<" ";
    127              cout<<endl;
    128          }*/
    129          hong_get(n);
    130          result=J_get(x0,y0);
    131          /*cout<<"***"<<endl<<endl;
    132          for(int j=1;j<11;j++){
    133             for(int i=1;i<10;i++)cout<<hong[j][i]<<" ";
    134              cout<<endl;
    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

  • 相关阅读:
    OCP 062【中文】考试题库(cuug内部资料)第13题
    OCP 062【中文】考试题库(cuug内部资料)第12题
    560. 和为K的子数组 力扣(中等) 字节面试题,不会,前缀和,hash,有尺取法的味道
    863. 二叉树中所有距离为 K 的结点 力扣(中等) bfs
    671. 二叉树中第二小的节点 力扣(简单) auto循环set
    1713. 得到子序列的最少操作次数 力扣(困难) 最长公共子序列->最长上升子序列 lower(vector) 得迭代器
    47. 全排列 II 力扣(中等) 手写练习
    328. 奇偶链表 力扣(中等) 链表练习
    21. 合并两个有序链表 力扣(简单) 链表练习
    1743. 从相邻元素对还原数组 力扣(中等) 需要思考但可以做,hash
  • 原文地址:https://www.cnblogs.com/farewell-farewell/p/5351701.html
Copyright © 2011-2022 走看看