Xiangqi(比较复杂的模拟)

4746: Xiangqi

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

总提交: 15            测试通过:2

描述

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 multiple 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’.

样例输入

2 1 4
G 10 5
R 6 4

3 1 5
H 4 5
G 10 5
C 7 5

0 0 0

样例输出

YES
NO

提示

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.

题意:黑方只有一枚将棋,红方则有多枚棋子,此时黑方动,判断黑方是否已经无路可走,即被将死。

题解:模拟判断红方棋子的走向,再判断黑将4个方向移动是否能被红方的棋子所将死。

  1 #include "iostream"
  2 #include "string.h"
  3 using namespace std;
  4 int weizhi[15][15];
  5 int wxl(int a,int b)
  6 {
  7     int i,flag;//flag判断此位置是否有棋子和有几个棋子
  8 //    判断马的走位
  9  if((a-2)>0&&(b-1)>0&&weizhi[a-2][b-1]==5&&!weizhi[a-1][b-1])return 0;
 10  if((a-2)>0&&(b+1)<=9&&weizhi[a-2][b+1]==5&&!weizhi[a-1][b+1])return 0;
 11  if((a-1)>0&&(b-2)>0&&weizhi[a-1][b-2]==5&&!weizhi[a-1][b-1])return 0;
 12  if((a+1)<=10&&(b-2)>0&&weizhi[a+1][b-2]==5&&!weizhi[a+1][b-1])return 0;
 13  if((a+2)<=10&&(b-1)>0&&weizhi[a+2][b-1]==5&&!weizhi[a+1][b-1])return 0;
 14  if((a+2)<=10&&(b+1)<=9&&weizhi[a+2][b+1]==5&&!weizhi[a+1][b+1])return 0;
 15  if((a-1)>0&&(b+2)<=9&&weizhi[a-1][b+2]==5&&!weizhi[a-1][b+1])return 0;
 16  if((a+1)<=10&&(b+2)<=9&&weizhi[a+1][b+2]==5&&!weizhi[a+1][b+1])return 0;
 17
 18 // 判断炮和车和将和帅是否直接对面
 19 flag=0;
 20  for(i=a-1;i>0;i--)
 21  {
 22      if(!flag&&weizhi[i][b]==3||weizhi[i][b]==4)return 0;
 23      if(weizhi[i][b]==2&&flag==1)return 0;
 24      if(weizhi[i][b]!=0)flag++;//判断炮有几个跳跃点
 25  }
 26  flag=0;
 27  for(i=a+1;i<=10;i++)
 28  {
 29      if(!flag&&weizhi[i][b]==3||weizhi[i][b]==4)return 0;
 30      if(weizhi[i][b]==2&&flag==1)return 0;
 31      if(weizhi[i][b]!=0)flag++;
 32  }
 33  flag=0;
 34  for(i=b-1;i>0;i--)
 35  {
 36      if(!flag&&weizhi[a][i]==3||weizhi[a][i]==4)return 0;
 37      if(weizhi[a][i]==2&&flag==1)return 0;
 38      if(weizhi[a][i]!=0)flag++;
 39  }
 40  flag=0;
 41  for(i=b+1;i<10;i++)
 42  {
 43      if(!flag&&weizhi[a][i]==3||weizhi[a][i]==4)return 0;
 44      if(weizhi[a][i]==2&&flag==1)return 0;
 45      if(weizhi[a][i]!=0)flag++;
 46  }
 47  return 1;//黑将不会被将军
 48 }
 49
 50 int main()
 51 {
 52     int i,k,n,m,b,c,flag;
 53     char a;
 54     while(cin>>n>>m>>k)
 55     {
 56         if(n==0&&m==0&&k==0)break;
 57         memset(weizhi,0,sizeof weizhi);//给位置初始化为0
 58         for(i=0;i<n;i++)
 59         {
 60             cin>>a>>b>>c;
 61             if(a==‘G‘)weizhi[b][c]=4;//4表示这个点的棋子是帅
 62             if(a==‘H‘)weizhi[b][c]=5;//5表示这个点的棋子是马
 63             if(a==‘C‘)weizhi[b][c]=2;//2表示这个点的棋子是炮
 64             if(a==‘R‘)weizhi[b][c]=3;//3表示这个点的棋子是车
 65         }
 66         //判断将的4个移动方向是否还会被将军
 67         if(m+1<=3&&m+1>0&&k>=4&&k<=6)//因为黑将的移动是有范围的,所以不能越界
 68         {
 69             flag=wxl(m+1,k);
 70             if(flag)
 71             {
 72                 cout<<"NO"<<‘\n‘;continue;
 73             }
 74         }
 75         if(m-1<=3&&m-1>0&&k>=4&&k<=6)
 76         {
 77             flag=wxl(m-1,k);
 78             if(flag)
 79             {
 80                 cout<<"NO"<<‘\n‘;continue;
 81             }
 82         }
 83         if(m<=3&&m>0&&k+1>=4&&k+1<=6)
 84         {
 85             flag=wxl(m,k+1);
 86             if(flag)
 87             {
 88                 cout<<"NO"<<‘\n‘;continue;
 89             }
 90         }
 91         if(m<=3&&m>0&&k-1>=4&&k-1<=6)
 92         {
 93             flag=wxl(m,k-1);
 94             if(flag)
 95             {
 96                 cout<<"NO"<<‘\n‘;continue;
 97             }
 98         }
 99         cout<<"YES"<<‘\n‘;
100     }
101 }
102 //但是TOJ有一点不用考虑,我也没考虑,其他oj则需要考虑,就是红方是用帅来将军的,这是轮到黑方
103 //移子,那么应该是黑方胜,而TOJ则还是红方胜 

原文地址:https://www.cnblogs.com/htmrc1/p/8449795.html

时间: 2024-10-12 15:34:22

Xiangqi(比较复杂的模拟)的相关文章

UVA 1589 Xiangqi(仔细的模拟)

题意:中国象棋大家都玩过,就是基本规则,只有将,帅,车,马,炮. 解题思路: 思路是把各个棋子能攻击到的位置在judge数组相应的位置上标记出来 首先考虑马蹩马腿的情况,这个比较好考虑,注意不要越界就行了. 车,不能穿过自己方的车,马,炮,帅.但范围可以穿过'将',因为'将'下一步会移动. 炮,不可以用'将'作为炮架,其余都可以,因为'将'下一步会移动. 帅,情况很简单.一条线. 要注意的是,每个棋子的攻击范围,是必须到另一个棋子的位置的 考虑数据 3 1 5 R 1 1 R 2 5 G10 5

HDU 4121 Xiangqi 模拟

原题: http://acm.hdu.edu.cn/showproblem.php? pid=4121 题目: Xiangqi Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4809 Accepted Submission(s): 1134 Problem Description Xiangqi is one of the most pop

UVa 1589 Xiangqi(模拟 HDU4121)

题意  给你一个黑方被将军的象棋残局  判断红方是否已经把黑方将死 模拟题  注意细节就行了  看黑方的将是否四个方向都不能走 #include<cstdio> #include<cstring> using namespace std; const int N = 12; char brd[N][N]; int dx[] = { -1, 1, 0, 0}, dy[] = {0, 0, -1, 1}; int hx[] = { -2, -1, -2, -1, 1, 2, 1, 2}

hdu4121 poj4001 Xiangqi(模拟)

模拟题考验coding能力,一定要思路清晰,按照模块化思想,有哪些情况,需要哪些功能都要事先分析好了.高手的模拟题代码往往结构很清晰,功能模块写成函数,没有过多重复代码,让人一看便明. 方法选择的好坏会影响编程复杂度,这题老将最多只能往四个位置走,就枚举这四个位置,每个位置再枚举每个红子看是不是有子能吃了它.枚举时注意有可能老将这一步吃了一个红子. 有一种情况是一开始双方老将就见面,这其实不叫红棋在将军,实际中红棋不能这么将.但是毕竟是一道编程题,出题人可能也不是太懂棋...所以要考虑这种情况.

UVA - 1589 Xiangqi (模拟)

Xiangqi 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

poj 4001 Xiangqi(模拟)

Xiangqi Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1357   Accepted: 347 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 e

UVA 1589:Xiangqi (模拟 Grade D)

题目: 象棋,黑棋只有将,红棋有帅车马炮.问是否死将. 思路: 对方将四个方向走一步,看看会不会被吃. 代码: 很难看……WA了很多发,还越界等等. #include <cstdio> #include <cstring> #include <cstdlib> char graph[13][13]; int go[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; bool inBlackPalace(int x, int y) { return

[HDOJ4121]Xiangqi(模拟)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4121 题意:象棋棋盘上有一方只有车马炮帅,另一方只有将,现在轮到将走,问是不是被将死了. 枚举所有被车马炮帅覆盖的位置,看看将还能不能有不被覆盖的地方走.这个题写起来好麻烦啊… 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 1

POJ Xiangqi 4001 &amp;&amp; HDOJ 4121 Xiangqi

题目链接(POJ):http://poj.org/problem?id=4001 题目链接(HDOJ):http://acm.hdu.edu.cn/showproblem.php?pid=4121 Xiangqi Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1108   Accepted: 299 Description Xiangqi is one of the most popular two-player boa