http://acm.hdu.edu.cn/showproblem.php?pid=4121​
这是一道模拟的题,大致是中国象棋的规则,然后给你输入红方和黑方的棋子,然后再给出红方的其它棋子,其它棋子只能为 车、马、炮,且棋盘一共只有8个棋子。题目中的情况是,现在轮到黑方来移动棋子,来判断是否已经把黑方的将“将死”。首先读完题目,就知道这是一道模拟题。需要模拟象棋的规则,对棋盘进行操作。而且,我们看到的是所有黑将能移动的位置都应该被将死。值得注意的是,在将军的情况下,由于黑方只有一个将,所以将在输入时的最初位置的时候其实不必被将军,因为它必须移动,所以就算将了军也是无用的。
所以,我们可以把所有类型的象棋来进行模拟,看是否能吃到将。

规则见原题。

我在做题的时候犯了一个错误,将不能在九宫格中按斜线来走,那是士走的路线。而且我的方法不用考虑将可以吃掉棋子的情况。还有就是注意程序中bool类型变量的位置很重要。
下面上代码,我的代码很长,可以简化。

/*HDU4121 UVa1589 Xiangqi0MS 1408K(HDU)@author: mukeran@link: http://www.mukeran.com
*/
#include<cstdio>
#include<cstring>
/*
P 是一个结构体来记录点的数据
变量声明:mat 是 bool,用来记录当前棋盘上位置是否有棋子B 是 P,用来记录黑将的位置G 是 P,用来记录红将的位置R 是 P 的一个数组,用来记录所有车的位置cntr 是 int,用来记录有多少个车H 是 P 的一个数组,用来记录所有马的位置cnth 是 int,用来记录有多少个马C 是 P 的一个数组,用来记录所有炮的位置cntc 是 int,用来记录有多少个炮symbol 是 char,用来输入时记录x 和 y 是 int,输入时的记录和黑将位置的代表blacks 是一个 P 的二维数组,用来记录在每个位置上的黑将能走到哪个位置上
*/
struct P {int x;int y;
}B, G, R[10], H[10], C[10];
char symbol;
bool mat[15][12];
P blacks[12][12] = { //black[0]作废,black[i][0].x用来记录有多少种情况,black[i][j]是P,用来记录点位置{}, {{x:2}, {x:1, y:5}, {x:2, y:4}},{{x:3}, {x:1, y:4}, {x:3, y:4}, {x:2, y:5}},{{x:2}, {x:2, y:4}, {x:3, y:5}},{{x:3}, {x:1, y:4}, {x:1, y:6}, {x:2, y:5}},{{x:4}, {x:2, y:4}, {x:1, y:5}, {x:3, y:5}, {x:2, y:6}},{{x:3}, {x:3, y:4}, {x:3, y:6}, {x:2, y:5}},{{x:2}, {x:2, y:6}, {x:1, y:5}},{{x:3}, {x:1, y:6}, {x:3, y:6}, {x:2, y:5}},{{x:2}, {x:2, y:6}, {x:3, y:5}}//这里有一个记录规则,y = 5 时,x += 3,y = 6 时,x += 6,当然 y = 4 时 x 不变//这里可以用另外的循环来实现
};
int n, x, y, cntr, cnth, cntc;
int main() {while(true) {scanf("%d%d%d", &n, &B.x, &B.y);if(n == 0) return 0;//数据清零memset(mat, 0, sizeof mat);memset(R, 0, sizeof R);memset(H, 0, sizeof H);memset(C, 0, sizeof C);cntr = cnth = cntc = 0;//输入for(int i = 1; i <= n; i++) {scanf("%s%d%d", &symbol, &x, &y);mat[x][y] = true;if(symbol == 'G') G.x = x, G.y = y;else if(symbol == 'R') R[++cntr].x = x, R[cntr].y = y;else if(symbol == 'H') H[++cnth].x = x, H[cnth].y = y;else if(symbol == 'C') C[++cntc].x = x, C[cntc].y = y;}bool ans = false; //ans用来记录当前位置是否能将军//读取点会走的位置int index = B.x;if(B.y == 5) index += 3;else if(B.y == 6) index += 6;x = y = 0;bool rec = false; //rec用来记录当前黑王的位置是否会覆盖一个原来的棋子,在恢复棋盘的是否要恢复for(int w = 1; w <= blacks[index][0].x; w++) {if(!rec) mat[x][y] = false; //抹掉上个王的位置x = blacks[index][w].x, y = blacks[index][w].y; //读取下一个王的位置if(mat[x][y]) rec = true; //检查王此时的位置上原来是否有棋子,并记录else rec = false;mat[x][y] = true; //标记王的位置ans = false;//首先是判断红将能否直接飞过去吃到黑将if(G.y == y) {ans = true;for(int j = x + 1; j < G.x; j++)if(mat[j][y]) {ans = false;break;}}if(ans) continue; //如果已经将了,下面的就不用判断了//判断车是否能把王吃掉for(int j = 1; j <= cntr; j++) {if(R[j].x == x) { //横向if(R[j].y < y) { //车在王左侧ans = true;for(int q = R[j].y + 1; q < y; q++)if(mat[x][q]) {ans = false;break;}}if(R[j].y > y) { //车在王右侧ans = true;for(int q = y + 1; q < R[j].y; q++)if(mat[x][q]) {ans = false;break;}}}else if(R[j].y == y) { //纵向if(R[j].x > x) { //车在王下侧ans = true;for(int q = x + 1; q < R[j].x; q++)if(mat[q][y]) {ans = false;break;}}if(R[j].x < x) { //车在王上侧ans = true;for(int q = R[j].x + 1; q < x; q++)if(mat[q][y]) {ans = false;break;}}}if(ans) break;}if(ans) continue;//判断马for(int j = 1; j <= cnth; j++)if((H[j].x - 2 == x && (H[j].y - 1 == y || H[j].y + 1 == y) && !mat[H[j].x - 1][H[j].y])||(H[j].x + 2 == x && (H[j].y - 1 == y || H[j].y + 1 == y) && !mat[H[j].x + 1][H[j].y])||(H[j].y - 2 == y && (H[j].x - 1 == x || H[j].x + 1 == x) && !mat[H[j].x][H[j].y - 1])||(H[j].y + 2 == y && (H[j].x - 1 == x || H[j].x + 1 == x) && !mat[H[j].x][H[j].y + 1])) {ans = true;break;}if(ans) continue;//判断炮for(int j = 1; j <= cntc; j++) {if(C[j].x == x) { //横向bool tmpf = false; //tmpf用来看炮和王之间是否会有多余的棋子if(C[j].y < y) { //炮在王左边ans = false;for(int q = C[j].y + 1; q < y; q++)if(mat[x][q]) {if(tmpf) {ans = false; //第二次找到炮之间的棋子,废止break;}else {tmpf = true; //第一次找到炮之间的棋子,成立ans = true;}}}else if(C[j].y > y) { //炮在王右边ans = false;for(int q = C[j].y - 1; q > y; q--)if(mat[x][q]) {if(tmpf) {ans = false;break;}else {tmpf = true;ans = true;}}}}else if(C[j].y == y) { //纵向bool tmpf = false;if(C[j].x > x) { //炮在王下面ans = false;for(int q = C[j].x - 1; q > x; q--)if(mat[q][y]) {if(tmpf) {ans = false;break;}else {tmpf = true;ans = true;}}}else if(C[j].x < x) { //上面ans = false;for(int q = C[j].x + 1; q < x; q++)if(mat[q][y]) {if(tmpf) {ans = false;break;}else {tmpf = true;ans = true;}}}}if(ans) break;}//如果到这里都没有将军的话,则说明不能将军if(!ans) {printf("NO\n");break;}}//如果所有情况都能将军的话,就可以完全将军if(ans) printf("YES\n");}
}

HDU4121 UVa1589 Xiangqi 解题报告相关推荐

  1. POJ4001 HDU4121 UVA1589 UVALive5829 Xiangqi【模拟+回溯】

    Xiangqi Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1791   Accepted: 444 Descriptio ...

  2. uscao 线段树成段更新操作及Lazy思想(POJ3468解题报告)

    线段树成段更新操作及Lazy思想(POJ3468解题报告) 标签: treequerybuildn2cstruct 2011-11-03 20:37 5756人阅读 评论(0) 收藏 举报  分类: ...

  3. 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  4. 【解题报告系列】超高质量题单 + 题解(ACM / OI)超高质量题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我新写的超高质量的题解和代码,题目难度不 ...

  5. 解题报告(三)多项式求值与插值(拉格朗日插值)(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  6. 解题报告(十三)中国剩余定理(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  7. 解题报告(四)生成函数(ACM/ OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  8. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  9. 解题报告(一)E、(BZOJ4589)Hard Nim(博弈论 + FWT)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  10. 解题报告(五)组合计数(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

最新文章

  1. java异常_Java的异常体系
  2. 零压力学python_《零压力学Python》 之 第一章知识点归纳
  3. 【JS 逆向百例】网洛者反爬练习平台第四题:JSFuck 加密
  4. 于小c三国语言_云顶之弈:三国成最强打工羁绊 校长教学顺滑转九五
  5. [模拟|数位] leetcode 7 整数反转
  6. 【每日一具17】CAD迷你画图/最新2020R9
  7. 毕设使用EndNote管理Word文献
  8. redis,ruby安装
  9. JSP实现学生管理系统
  10. Kettle (1) - 读取 CSV 文件
  11. 英语语法——定语从句
  12. 计算机语言培训机构排行榜,TIOBE 2月编程语言排行榜
  13. xpwifi热点设置android,笔记本xp系统wifi热点设置教程(图文)
  14. 【OpenCV入门教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
  15. buu——girlfriend
  16. 随机误差与Allan方差的理解
  17. 关于dva框架的二三事
  18. [转]常用网络协议分析工具
  19. Ubuntu 下安装Chrom浏览器
  20. 揭秘奥运会四大难解之谜

热门文章

  1. numpy的array_equal函数
  2. 网站打开速度慢是什么原因导致
  3. YTU 2577: 小数计算——结构体
  4. 话费充值api接口 手机话费充值功能接入
  5. 基于股票大数据分析的Python入门实战(实践记录)(持续更新)
  6. collapse组件样式 react_antd源码分析之——折叠面板(collapse)
  7. RAC-iOS中基本用法
  8. Linux下抓取log的方法
  9. PSD是什么文件格式
  10. 幻灯片制作去除模板背景