[刷题]算法竞赛入门经典(第2版) 4-1/UVa1589 - Xiangqi

书上具体所有题目:http://pan.baidu.com/s/1hssH0KO
代码:(Accepted,0 ms)

//UVa1589
#include<iostream>
#include<cmath>
#define P(x,y) Pi[x].position[y]
using namespace std;
int N;//2<=N<=7
bool A[4];//around,储存"将"周围是不是已经不能走了  0上 1左 2下 3右
struct piece {char name;int position[2];//0x 1y
}Pi[10];inline bool f1(int i, int j, bool po) {//判断第j个子是否堵在第i个子前面,针对"车"和"帅"和"炮"if (P(i, (po + 1) % 2) != P(j, (po + 1) % 2)) return 0;int ii = P(i, po) - P(0, po), jj = P(j, po) - P(0, po);if (ii > 0 && jj > 0 && ii > jj) return 1;if (ii < 0 && jj < 0 && ii < jj) return 1;return 0;
}
inline bool f2(int i) {//判断第i个子是不是在"将"周围if (P(i, 0) == P(0, 0) && abs(P(i, 1) - P(0, 1)) == 1) return 1;if (P(i, 1) == P(0, 1) && abs(P(i, 0) - P(0, 0)) == 1) return 1;return 0;
}
bool f3(int i, int xx, int yy) {//判断"马"是否可以到达"将"周围if ((abs(xx) == 2 && abs(yy) == 1) || (abs(xx) == 1 && abs(yy) == 2)) {for (int j = 0;j <= N;++j) {if (P(j, 0) == P(i, 0) - int(xx / 2) && P(j, 1) == P(i, 1) - int(yy / 2)) return 0;//cerr <<"H:"<<i<<' '<<j<<'\t'<< P(j, 0) << ' ' << P(i, 0) - int(xx / 2) << '\t' << P(j, 0) << ' ' << P(i, 1) - int(yy / 1) << '\n';//-------------------}return 1;}return 0;
}
void GR(int i, bool po) {//"将"和"车"的函数if (P(i, (po + 1) % 2)>P(0, (po + 1) % 2) + 1 || P(i, (po + 1) % 2) < P(0, (po + 1) % 2) - 1) return;int j = 1;for (;j <= N&&!f1(i, j, po);++j);if (j > N) {if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) - 1) { if (!f2(i)) A[(po + 1) % 2] = 1; }else if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) + 1) { if (!f2(i))A[(po + 1) % 2 + 2] = 1; }else if (f2(i)) P(i, po) - P(0, po) > 0 ? A[po] = 1 : A[po + 2] = 1;else A[po] = A[po + 2] = 1;}
}
void H(int i) {//"马"的函数if (f2(i)) return;if (!A[0] && f3(i, P(i, 0) - (P(0, 0) - 1), P(i, 1) - P(0, 1))) A[0] = 1;if (!A[1] && f3(i, P(i, 0) - P(0, 0), P(i, 1) - (P(0, 1) - 1))) A[1] = 1;if (!A[2] && f3(i, P(i, 0) - (P(0, 0) + 1), P(i, 1) - P(0, 1))) A[2] = 1;if (!A[3] && f3(i, P(i, 0) - P(0, 0), P(i, 1) - (P(0, 1) + 1))) A[3] = 1;
}
void C(int i, bool po) {//"炮"的函数if (f2(i) || P(i, (po + 1) % 2) > P(0, (po + 1) % 2) + 1 || P(i, (po + 1) % 2) < P(0, (po + 1) % 2) - 1) return;int flag = 0;for (int j = 1;j <= N;++j) if (f1(i, j, po)) ++flag;if (flag == 1) {if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) - 1) A[(po + 1) % 2] = 1;else if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) + 1) A[(po + 1) % 2 + 2] = 1;else {int j = 1;for (;j <= N;++j) if (f1(i, j, po) && f2(j)) break;if (j <= N) P(i, po) - P(0, po) > 0 ? A[po] = 1 : A[po + 2] = 1;else A[po] = A[po + 2] = 1;}}
}int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);while ((cin >> N >> P(0, 0) >> P(0, 1)) && N && P(0, 0) && P(0, 1)) {for (int i = 1;i <= N;++i)cin >> Pi[i].name >> P(i, 0) >> P(i, 1);A[0] = (P(0, 0) == 1 ? 1 : 0);A[1] = (P(0, 1) == 4 ? 1 : 0);A[2] = (P(0, 0) == 3 ? 1 : 0);A[3] = (P(0, 1) == 6 ? 1 : 0);//cerr << "A:" << A[0] << '\t' << A[1] << '\t' << A[2] << '\t' << A[3] << "\n";//--------for (int i = 1;i <= N;++i) {if (Pi[i].name == 'G') GR(i, 0);else if (Pi[i].name == 'R') GR(i, 0), GR(i, 1);else if (Pi[i].name == 'H') H(i);else C(i, 0), C(i, 1);}int i;//cerr << "A:" << A[0] << '\t' << A[1] << '\t' << A[2] << '\t' << A[3] << "\n";//--------for (i = 0;i < 4 && A[i];++i);cout << (i < 4 ? "NO" : "YES") << '\n';}return 0;
}

分析:
看着挺烦的,以为会调试很久,有那么多情况,感觉还不好找出错的点。结果两遍就AC了,喜出望外~
我的思路是,判断每个子有没有把“将”周围堵住,对棋子大循环。同时我没有定义9*10的大棋盘。(现在想想定义了个棋盘好像简单好多。甚至可以打表查看哪里红子可以到达。或许我太过在意空间的占用了)
A[4]的0上 1左 2下 3右是有顺序要求的,这样定义可以方便地和po对应起来。
车炮帅的攻击范围都是直线,所以定义的函数只针对其中一个方向,而G只能是向x轴方向出击,所以是只使用向x轴(po=0)方向的函数,而车和炮要使用两次函数。这三者有两种情况将军,第一是指向“将”旁边,使“将”无法向旁边行走。另一种是直接指向“将”,使之只能往旁边走不能在车炮指向的方向行走。三者都得考虑被堵住看不见“将”的情况。
不过这题有个小bug,就是将和帅面对面的情况,将可以直接飞过去翻盘赢了,无需躲闪。但是题目好像没有考虑这种情况,应该是规避了这类输入数据。我也是点击“Submit”时突然想起来这个情况没写。。。不过竟然AC了,那就算了。。。
还有就是车和炮直接在将旁边的情况,将可以吃掉它们消除威胁(当然前提是没有别人可以吃这个位置)。这个情况下,比如红车在(1,6),黑将在(1,5),那么黑将可以向右吃掉它,但是不能向左,因为向左进入(1,4)后车依然可以吃“将”。这是比较特殊的。
还有就是这一段:

//在GR(...)函数的最后几行
if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) - 1) { if (!f2(i)) A[(po + 1) % 2] = 1; }
else if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) + 1) { if (!f2(i))A[(po + 1) % 2 + 2] = 1; }

本来我写的是

if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) - 1) A[(po + 1) % 2] = 1;
else if (P(i, (po + 1) % 2) == P(0, (po + 1) % 2) + 1) A[(po + 1) % 2 + 2] = 1;

没有后面的if。结果出现的问题就是当比如车在(1,6),将在(1,5)时,会判定为在针对x轴方向时,(1,6)(即将右侧,即A[3])是将不可以走的。
还有炮的函数C,对于该函数最后几行,

else {int j = 1;for (;j <= N;++j) if (f1(i, j, po) && f2(j)) break;if (j <= N) P(i, po) - P(0, po) > 0 ? A[po] = 1 : A[po + 2] = 1;else A[po] = A[po + 2] = 1;}

意思是,如果炮架子刚好在将前面,那么炮只能攻击将的后面(即“将”不能后移),将前面即跑架子所在那个点打不到。
马的函数竟然算是最简单的了。。判断够不够得到将旁边的点,已及马有没有蹩脚即可。

附:uDebug上看到的测试数据:
2 1 4
G 10 5
R 6 4

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

2 1 5
R 4 4
G 10 5

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

4 1 5
G 10 4
C 6 5
H 5 5
R 1 1

5 1 5
G 10 4
C 6 5
H 5 5
H 4 5
R 1 1

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

3 1 5
G 10 4
R 5 5
R 1 6

4 1 5
G 10 4
R 5 5
R 1 6
H 3 7

0 0 0

转载于:https://www.cnblogs.com/xienaoban/p/6798106.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenMap教程–第1部分

介绍 本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。 OpenMap的开发人员指南是非常有用的文档&#xff0c;描述了OpenMap的体系结构&#xff0c;但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用&#xff0c;但还不够。 OpenMap是用…

killall 后面信号_Linux 下使用 killall 命令终止进程的 8 大用法

Linux 的命令行提供很多命令来杀死进程。比如&#xff0c;你可以向 kill 命传递一个PID来杀死进程&#xff1b;pkill 命令使用一个正则表达式作为输入&#xff0c;所以和该模式匹配的进程都被杀死。但是还有一个命令叫 killall &#xff0c;默认情况下&#xff0c;它精确地匹配…

分享一些我的远程办公经验

前言 大家好&#xff0c;我叫孙叫兽&#xff0c;本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢&#xff0c;因为从事的开发项目比较保密&#xff0c;比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

SqlServer按中文数字排序

表数据: 按名称排序 并不能得到一二三四五六的顺序 select * from LiWei order by name 找到中文数字在一二三四五六七八九十的位置 select id,name,SUBSTRING(name,2,1) as 中文数字,charindex(SUBSTRING(name,2,1),一二三四五六七八九十) as 中文数字所在位置 from LiWei 按中…

C语言--直接插入排序【排序算法|图文详解】

一.直接插入排序介绍&#x1f357; 直接插入排序又叫简单插入排序&#xff0c;是一种简单直观的排序算法&#xff0c;它通过构建有序序列&#xff0c;对于未排序的数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 算法描述&#xff1a; 假设要排序…

python 读取sqlite存入文件_如何通过python读取sqlite数据文件

sqlite简介&#xff1a;sqlite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它的设计目标是嵌入式的&#xff0c;而且目前已经在很多嵌入式产品中使用了它(如安卓系统)&#xff0c;它占用资源非常的低&#xff0c;在嵌入式设…

分享一些前端优质的掘金小册,学完技术感觉已经超神了

大家好&#xff0c;本期内容给大家推荐一些优质的前端掘金小册&#xff0c;基本每个都是专栏小册的形式&#xff0c;比较适合初学者及工作几年的前端小伙伴&#xff0c;里面的内容讲解的比较详细&#xff0c;作者也是一线的大厂工作者。有兴趣的小伙伴快来打卡看一下吧&#xf…

sp烘焙流程_次世代86机甲战神制作全流程

1介绍Hello&#xff0c;大家好&#xff01;我叫周玉亮。首先感谢一下小左老师对我的作品的认可&#xff0c;以及给予我这次宝贵的分享机会。本次分享的是我的第一个次世代硬表面作品&#xff0c;名为《86机甲战神》&#xff0c;制作时间3周。时间还是相当紧的&#xff0c;要在3…

esper_Twitter4j和Esper:在Twitter上跟踪用户情绪

esper对于复杂事件处理和Twitter API的新手&#xff0c;我希望这是一个简短的教程&#xff0c;可以帮助他们Swift起步。 管理大数据并从中挖掘有用的信息是当前技术中最热门的讨论主题。 来自Twitter&#xff0c;Facebook和Linkedin等社交网络的半结构化数据的爆炸式增长使Hado…

前端实现流星雨特效

目录 前言 效果图&#xff1a; HTML CSS 完整代码 前言 使用htmlcss实现简单得浏览器特效&#xff0c;在编译器用导入项目&#xff0c;直接在浏览器打开即可&#xff0c;效果十分得炫酷&#xff0c;十分得哇塞&#xff0c;女朋友直呼NB! 效果图&#xff1a; HTML <!DO…

RxJava线程控制

RxJava中的线程转换主要通过下面两个方法&#xff1a; 1.subscribeOn 2.observeOn 一、subscribeOn 1.调用一次subscribeOn时&#xff1a; Observable observable; Schedulers schedulers; Observer observer; observable.subscribeOn(schedulers).subscribe(observer) 通过解析…

elementui中tabs切换item中的内容会变_中后台UX优化之道

前言“前台重体验&#xff0c;后台重逻辑”&#xff0c;B端谈 UX 有没有价值&#xff1f;一切电子化的今天&#xff0c;运营、审核、电销、账务……无数岗位依赖中后台系统来完成他们的日常工作&#xff0c;好的 UX 确实可以直接为这些产能提效当中后台的工程师们花费了巨大精力…

介体设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

判断一个对象是否是空对象的处理办法

目录 前言 方法一&#xff0c;Object.keys()方法&#xff0c;返回对象的属性名组成的一个数组&#xff0c;若长度为0&#xff0c;则为空对象 方法二、for in循环 方法三&#xff1a;将对象转换成字符串&#xff0c;再判断是否等于“{}” 前言 在维护客户基本信息的时候包含…

Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh

Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh前&#xff0c;要先清除之前的crs配置信息 # /u01/app/11.2.0/grid/crs/install/rootcrs.pl -verbose -deconfig -force # /u01/app/11.2.0/grid/root.sh转载于:https://www.cnblogs.com/abclife/p/5725962.html

jvm需要多长时间才能进行转义分析? 可能比您想象的要长。

这篇文章着眼于转义分析&#xff0c;特别是jvm在运行的程序中执行转义分析需要多长时间。 我做了一些观察&#xff0c;但目前还没有全部解释。 作为介绍&#xff0c;让我们绕道看看jvm -Xcomp中一个鲜为人知且使用更少的标志&#xff08;这将是一件好事&#xff09;。 该标志…

postgres 判断null_PostgreSQL NULLIF()用法及代码示例

PostgreSQL的有一个NULLIF函数来处理空值。这个NULLIF函数是PostgreSQL提供的最常见的条件表达式之一。 用法:NULLIF(argument_1,argument_2); 这个NULLIF如果函数返回空值参数_1等于参数_2,否则返回参数_1。 例: 首先,我们创建a 表名为帖子如下: CREATE TABLE posts ( id…

Linux常用操作指令整理,这个操作服务器实在是太方便了

目录 前言 常用指令 系统管理命令 打包压缩相关命令 关机/重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 更改文件的用户及用户组 文件权限管理 更改权限 前言 由于在银行工作&#xff0c;一个项目需要在云桌面、SIT、UAT、小版本、联调环境、准生产…

http invoker_Http Invoker的Spring Remoting支持

http invokerSpring HTTP Invoker是Java到Java远程处理的重要解决方案。 该技术使用标准的Java序列化机制通过HTTP公开服务&#xff0c;并且可以看作是替代方法&#xff0c;而不是Hessian和Burlap中的自定义序列化。 而且&#xff0c;它仅由Spring提供&#xff0c;因此客户端和…

前端实现数字快速递增_天正CAD教程之递增文字应用实例

好课推荐&#xff1a;1、CAD2014&#xff1a;点击查看 2、室内&全屋&#xff1a;点击查看 3、CAD2019&#xff1a;点击查看4、CAD2018&#xff1a;点击查看5、Bim教程&#xff1a;点击查看 6、室内手绘&#xff1a;点击查看7、CAD三维&#xff1a;点击查看8、全屋定制&…