原题及翻译

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).
象棋在一块10×9的棋盘上演奏,棋子放在交叉点上。
The top left point is (1,1) and the bottom right point is (10,9).
左上点为(1,1),右下点为(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:
我们只使用以下4种材料:

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”.
马:如左图所示,马有8种跳跃动作和捕捉。然而,如果有任何棋子水平或垂直地躺在马的相邻点上,它就不能在该方向上移动(见下面的图),这被称为“马腿的蹒跚(蹩马腿)<真亏百度敢翻译成这样>”。

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 (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’.
输入
输入包含的测试用例不超过40个。对于每一个测试用例,第一行包含三个整数,表示红色块数n(2≤n≤7)和黑色常规的位置。下面的n行包含n个红色棋子的详细信息。对于每一行,有一个字符和两个整数表示棋子的类型和位置(类型char ‘G’表示将/帅,R’表示战车,H’表示马,C’表示大炮)。我们保证这种情况是合法的,并且红方已经将军。两个测试用例之间有一个空白行。输入以“0 0 0”结尾。

Output

For each test case, if the situation is checkmate, output a single word ‘YES’, otherwise output the word ‘NO’.
Hint: In the first situation, the black general is checked by chariot and “flying general”. In the second situa- tion, the black general can move to (1, 4) or (1, 6) to stop check. See the figure on the right.

输出
对于每个测试用例,如果情况是“将死”,
则输出单个单词“yes”,否则输出单词“no”。
提示:
在第一种情况下,黑将军由战车和“飞将军”检查。
在第二种情况下,黑将军可以移动到
(1,4)或(1,6)停止检查。
请参见右侧的图。
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

思路

1.象棋棋盘,首先想到建立一个二维数组,用来存储棋盘的每一个节点。
2.整体思路有两种(或者说我就能想到两种):
第一种:遍历所有的红棋棋子,标记出红方的攻击范围,然后找出黑棋将军的移动范围,判断其移动范围是否是红棋攻击范围的子集,如果是,则“将死”;
第二种:先找出黑棋将军所有的移动范围,判断每一个移动后可能遭到的红方棋子威胁,如果所有的移动方案都不可行,则“将死”。
3.分类讨论的思想,不管是那种方案,都需要分情况讨论。

完整代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int CheckerboardR[11][10];    //红棋盘
int CheckerboardB[11][10];   //黑棋盘
int red_number,Generalx,Generaly;
struct piece
{//声明棋子结构char type;int x;int y;
};
void General_scope(int x,int y)
{//黑棋将军的移动范围,利用20标识出来if(x+1<=3) CheckerboardB[x+1][y]=20;if(x-1>=1) CheckerboardB[x-1][y]=20;if(y+1<=6) CheckerboardB[x][y+1]=20;if(y-1>=4) CheckerboardB[x][y-1]=20;
}
int s_l_o_c_a_i_c(int x1,int y1,int x2,int y2)
{//判断两个棋子是否在同一行或同一列以及两个棋子之间是否有其它的棋子。if(x1==x2){//如果在同一行。int flag=1;for(int i=x1+1;i<x2;i++){//遍历从x1+1到x2的所以棋盘位置if(CheckerboardR[x1][i]!=0){//如果有其它棋子flag=0;}}if(flag){//如果两个棋子在同一行并且之间没有其它的棋子,返回10。return 10;}else{//如果两个棋子在同一行并且之间有其它的棋子,返回11。return 11;}}else if(y1==y2){//如果在同一列。int flag=1;for(int i=y1+1;i<y2;i++){//遍历从y1+1到y2的所以棋盘位置if(CheckerboardR[i][y1]!=0){//如果有其它棋子flag=0;}}if(flag){//如果两个棋子在同一列并且之间没有其它的棋子,返回20。return 20;}else{//如果两个棋子在同一列并且之间有其它的棋子,返回21。return 21;}}else{//如果既不在同一行,也不在同一列,返回0.return 0;}
}
void p_t_c_p_a_j_t_s_o_d(char type,int x,int y)
{//将输入的棋子放到棋盘上,并标记出该棋子统治的范围switch (type){case 'G':{//如果红棋是帅for(int i=x+1;i>=1;i--){if(CheckerboardR[i][y]==1||CheckerboardR[i][y]==2)break;else if(CheckerboardR[i][y]==0||CheckerboardR[i][y]==10)CheckerboardR[i][y]=10;}}case 'R':{//如果红棋是车for(int i=x-1;i>=1;i--){if(CheckerboardR[i][y]==1||CheckerboardR[i][y]==2)break;else if(CheckerboardR[i][y]==0||CheckerboardR[i][y]==10)CheckerboardR[i][y]=10;}for(int i=x+1;i<=10;i++){if(CheckerboardR[i][y]==1||CheckerboardR[i][y]==2)break;else if(CheckerboardR[i][y]==0||CheckerboardR[i][y]==10)CheckerboardR[i][y]=10;}for(int i=y+1;i<=9;i++){if(CheckerboardR[i][y]==1||CheckerboardR[i][y]==2)break;else if(CheckerboardR[i][y]==0||CheckerboardR[i][y]==10)CheckerboardR[x][i]=10;}for(int i=y-1;i>=1;i--){if(CheckerboardR[i][y]==1||CheckerboardR[i][y]==2)break;else if(CheckerboardR[i][y]==0||CheckerboardR[i][y]==10)CheckerboardR[x][i]=10;}}case 'H':{//如果红棋是马if(x+1==0||x+1==10){CheckerboardR[x+2][y-1]=10;CheckerboardR[x+2][y+1]=10;}if(x-1==0||x-1==10){CheckerboardR[x-2][y-1]=10;CheckerboardR[x+2][y+1]=10;}if(y-1==0||y-1==10){CheckerboardR[x+1][y-2]=10;CheckerboardR[x-1][y-2]=10;}if(y+1==0||y+1==10){CheckerboardR[x+1][y+2]=10;CheckerboardR[x-1][y+2]=10;}}case 'C':{//如果红棋是炮if(s_l_o_c_a_i_c(x,y,Generalx,Generaly)==11||s_l_o_c_a_i_c(x,y,Generalx,Generaly)==21){//判断炮与黑棋将军是否在同一条线上,以及中间是否有其它棋子for(int i=x-1;i>=1;i--){int x1=0,y1=0;if(CheckerboardR[i][y]==1&&CheckerboardR[i][y]==2){x1=i;y1=y;{for(int j=x1-1;i>=1;j--){if(CheckerboardR[j][y]==1&&CheckerboardR[j][y]==2)break;elseCheckerboardR[j][y]=10;}}}}}for(int i=y-1;i>=1;i--){int x1=0,y1=0;if(CheckerboardR[x][i]==1&&CheckerboardR[x][i]==2){x1=x;y1=i;for(int j=y1-1;i>=1;j--){if(CheckerboardR[x][j]==1&&CheckerboardR[x][j]==2)break;elseCheckerboardR[x][j]=10;}}}for(int i=y+1;i<=9;i++){int x1=0,y1=0;if(CheckerboardR[x][i]==1&&CheckerboardR[x][i]==2){x1=x;y1=i;for(int j=y1+1;i<=9;j++){if(CheckerboardR[x][j]==1&&CheckerboardR[x][j]==2)break;elseCheckerboardR[x][j]=10;}}}}}
}
int main ()
{//主函数,用于输入数据和做最后的判断memset(CheckerboardR,0,sizeof(CheckerboardR));memset(CheckerboardB,0,sizeof(CheckerboardB));while(1){cin>>red_number>>Generalx>>Generaly;//读入红方棋子是数和黑棋将军的坐标,这些坐标都作为全局变量声明CheckerboardB[Generalx][Generaly]=2;//在黑棋盘上将黑棋将军的坐标记录下来if(red_number==0||Generalx==0||Generaly==0) break;//用于结束输入struct piece red_piece[red_number];//声明一个存储红棋棋子结构的数组for(int i=1;i<=red_number;i++){//将red_number行的红棋子数据读入cin>>red_piece[i].type;scanf("%d %d",&red_piece[i].x,&red_piece[i].y);//存储红棋棋子的类型和坐标CheckerboardR[red_piece[i].x][red_piece[i].y]=1;//在红棋棋盘上把相应的位置标出来}for(int i=1;i<=red_number;i++){//利用函数将red_number行红棋的攻击范围标识出来p_t_c_p_a_j_t_s_o_d(red_piece[i].type,red_piece[i].x,red_piece[i].y);}General_scope(Generalx,Generaly);//调用函数将黑棋将军的移动范围标识出来//开始判断黑棋移动范围是否是红棋攻击范围的子集int checkmate1=0,checkmate2=0; //定义判断是否“将死”的变量for(int i=1;i<=3;i++){for(int j=4;j<=6;j++){/*经过一系列的函数处理之后,红棋的攻击范围与黑棋的移动范围被标识出来*/if(CheckerboardB[i][j]==20) checkmate1++;//如果遇到黑棋盘上标有20的位置,累加checkmate1if(CheckerboardB[i][j]==20&&CheckerboardR[i][j]==10) checkmate2++;//如果遇到黑棋盘上标有20,红棋盘上标有10的位置,累加checkmate2}}if(checkmate1==checkmate2) printf("YES \n");else printf("NO \n");memset(CheckerboardR,0,sizeof(CheckerboardR));memset(CheckerboardB,0,sizeof(CheckerboardB));//将两张棋盘重置,为下次输入做准备}
return 0;
}

测试

结语

看来英语不好也是个大问题啊,不然连ACM的题目都看不懂。
还有,百度翻译,哎,无力吐槽。

每天磕一道ACM 2月1日打卡

《算法竞赛入门经典》 习题4-1(象棋 Xiangqi ACM ICPC Fuzhou 2011,UVa1589)——仅提供大体方法相关推荐

  1. 象棋 (Xiangqi, ACM/ICPC Fuzhou 2011, UVa1589)

    Description Xiangqi is one of the most popular two-player board games in China. The game represents ...

  2. 《算法竞赛入门经典》 习题 4-1 (Xiangqi, ACM/ICPC Fuzhou 2011, UVa1589,hdoj_4121)

    原题: [hdoj链接](http://acm.hdu.edu.cn/showproblem.php?pid=4121) Problem Description Xiangqi is one of t ...

  3. 算法竞赛入门经典 习题3-2 分子量 Molar Mass

    给出一种物质的分子式(不带括号),求其分子量.本题分子式中只包含四种原子,分别为C.H.O.N,原子量分别为12.01,1.008,16.00,14.01.例如,C6H5OH的分子量为94.108g/ ...

  4. 算法竞赛入门经典|习题3-8, 循环小数(UVa202)

    耗时:1小时22分. 储备知识: 1.循环节 如果无限小数点后,从某一位起向右进行到某一位止的数字循环出现,首位衔接,则称这个小数为循环小数,这段数字为循环节. 例如: 547/7 = 78.(142 ...

  5. UVa 220 黑白棋 算法竞赛入门经典 习题4-3

    输出格式输出格式输出格式!UVaOJ的输出控制让我想起了玩黑魂时的感觉. 这道题难点在M操作后的输出 "Black - " 一眼看去'-'后面是两个个空格,然而事实是-与后面的数字 ...

  6. 算法竞赛入门经典 习题6-14

    UVa12118 Inspector's Dilemma 每两个城市之间都有道路连通,检查员要通过指定的道路,途中可以经过其它未指定的道路.通过每条道路的时间是一样的,求出通过所有指定道路要花费的最小 ...

  7. 算法竞赛入门经典 习题6-12

    UVa810 A Dicey Problem 一个迷宫里有一骰子,骰子可以上下左右移动的条件是相邻格中的数字和骰子朝上面的数字相同,或者相邻格子中为*.求一条从起点出发,最终回到起点的路径. 深搜和广 ...

  8. 刘汝佳《算法竞赛入门经典(第二版)》习题(六)

    刘汝佳<算法竞赛入门经典(第二版)>第四章习题(4-1~4-3) 习题4-1 象棋(Xiangai,ACM/ICPC Fuzhou 2011,UVa1589) 考虑一个象棋残局,其中红方有 ...

  9. 算法竞赛入门经典(第二版)第三章习题

    声明:作者水平有限,只是会基础C语言的小菜,C++还未入门.作者仅根据算法竞赛入门经典(第二版)书上第三章习题所述题意而编写,并未严格按照原题的输入输出编写,代码仅经过个人测试(OJ网站太慢了).代码 ...

最新文章

  1. ONNX MLIR方法
  2. 原来Transformer就是一种图神经网络,这个概念你清楚吗?
  3. C++ cout格式化输出
  4. Oracle DG常用视图与运维护常用操作
  5. NLP大魔王 · BERT 全解读
  6. 怎样在计算机上注册dll文件,注册dll文件【搞定步骤】
  7. python控制电机正反转_树莓派Python控制步进电机
  8. 汉字在c语言中用什么表示,在C语言中显示汉字
  9. contrastive CAM
  10. cz.cc免费域名申请教程(因为有朋友不知道怎么操作,特写此简单教程)
  11. 抓取2021百科知识竞赛题库和答案
  12. excel插入页码_当EXCEL遇上PPT 学做抢手人气王
  13. 基于imx8的成熟360全景方案 ,NVP6324+IMX8,N4+IMX8
  14. 动网8.2版本的注入漏洞的利用
  15. 转载: React Native 采用Fetch方式发送跨域POST请求
  16. 如何给孩子选绘本:绘本筛选实践分享
  17. JavaEye范凯谈唐骏造假事件
  18. c语言旅店管理系统结构图,C语言 旅店管理系统.doc
  19. MATLAB-函数图像绘制
  20. 如何使用工作日计算器?

热门文章

  1. 写个Fragment方便的抽象基类 BaseFragment
  2. 5.js模式-职责链模式
  3. CSS背景颜色转换(自动生成IE8以下的filter,兼容IE9)
  4. Tomcat源码解读系列(二)——Tomcat的核心组成和启动过程
  5. Hadoop安装记录
  6. java改写weka中的算法_用Eclipse在Weka中嵌入新算法
  7. java委托事件与观察者模式_多播委托与观察者模式联合使用,以及委托与事件的区别...
  8. ajax 入参为list_ajax向后台传入List
  9. Java黑皮书课后题第7章:*7.33(文化:中国生肖)使用一个字符串数组存储动物名称来简化程序清单3-9的程序
  10. 设置静态ip上网_开始使用第一步:连上网线换个皮