• hdu 4121 Xiangqi


    Xiangqi

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5421    Accepted Submission(s): 1286


    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.
     
    Source
     
    Recommend
    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
    ");
     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
    ");
     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
    ");
    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
    ");
    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
    ");
    127                 continue;
    128             }
    129         }
    130         printf("YES
    ");  ///没有出现为将死的情况,输出YES
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    【今日CV 视觉论文速览】 19 Nov 2018
    【numpy求和】numpy.sum()求和
    【今日CV 视觉论文速览】16 Nov 2018
    【今日CV 视觉论文速览】15 Nov 2018
    poj 2454 Jersey Politics 随机化
    poj 3318 Matrix Multiplication 随机化算法
    hdu 3400 Line belt 三分法
    poj 3301 Texas Trip 三分法
    poj 2976 Dropping tests 0/1分数规划
    poj 3440 Coin Toss 概率问题
  • 原文地址:https://www.cnblogs.com/pshw/p/5527709.html
Copyright © 2020-2023  润新知