题目:(传送门)

给出一个象棋的残局,下一步是黑棋走,判断黑棋是不是被将死。

思路:

读完这个题,知道是一个模拟题,然后想到用两个二维数组来模拟棋盘,一个(mp数组)用来存残局,一个(res数组)用来处理红棋在棋盘上产生的对黑棋的限制。

将红棋的马、车、炮、将写成函数来分别处理。这样处理完之后,判断一下黑棋的四周是不是有可以走的格子,有的话不是将死,没有的是就是被将死了。

1、可以将车和将写成一个函数来处理,这里可以标记与棋子处于同一行和同一列中的格子,如下图:

红色圈出来的部分不能走,注意马上边的格子是可以走的,而如果和车一行的只有对方的将,那么这一行都不能走。

2、对马的处理,如下图:

同理,红色的部分不能走,注意马有蹩腿的情况出现如上右图

3、对炮棋的处理最为复杂,具体情况如图:

如上右图中绿色的部分是可以走的,左图中的红色部分是不可以走的。

代码:(略长)

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e9;
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = ;//G-general-1 R-chariot-2 C-cannon-3 H-horse-4 Black-5
map<char,int> key;
int mp[][],res[][];
int N,bx,by;
struct T{
char ch;
int x,y;
}t[]; bool isIn(int x,int y) {//判断是不是在棋盘的范围内
if(x>= && x<= && y>= && y<=) {
return true;
}
return false;
} void makeGR(int x,int y) {//处理车和将的关系
if(isIn(x,y)) {
for(int i=x-; i>=; i--) { //Up
res[i][y] = -;
if(mp[i][y]!= && mp[i][y]!='B') {//从当前位置起到另外的第一个棋子(不包括黑棋)中间的位置都是不可以走的
break;
}
}
for(int i = x+; i<=; i++) { //Down
res[i][y] = -;
if(mp[i][y]!= && mp[i][y]!='B') {
break;
}
}
for(int i = y-; i>=; i--) { //Left
res[x][i] = -;
if(mp[x][i]!= && mp[x][i]!='B') {
break;
}
}
for(int i = y+; i<=; i++) { //Right
res[x][i] = -;
if(mp[x][i]!= && mp[x][i]!='B') {
break;
}
}
}
} void makeH(int x,int y) {//处理马棋
if(isIn(x-,y-) && mp[x-][y]==) { //Up//排除蹩腿的情况一共八个方向
res[x-][y-] = -;
}
if(isIn(x-,y+) && mp[x-][y]==){
res[x-][y+] = -;
}
if(isIn(x+,y-) && mp[x+][y]==) { //Down
res[x+][y-] = -;
}
if(isIn(x+,y+) && mp[x+][y]==){
res[x+][y+] = -;
}
if(isIn(x-,y-) && mp[x][y-]==){//Left
res[x-][y-] = -;
}
if(isIn(x+,y-) && mp[x][y-]==){
res[x+][y-] = -;
}
if(isIn(x-,y+) && mp[x][y+]==) { //Right
res[x-][y+] = -;
}
if(isIn(x+,y+) && mp[x][y+]==){
res[x+][y+] = -;
}
} void makeC(int x,int y) {//处理炮棋
if(x==&&(y>=&&y<=)) {
if(mp[][y]!= && mp[][y]!='B'){
res[][y] = -;
}
}
int tx=,ty=;
for(int i = x-; i>=; i--) { //Up
if(isIn(i,y) && mp[i][y]!= && mp[i][y]!='B') {//寻找与炮棋一行的棋子的位置(不包括黑棋)
tx = i,ty = y; //cout<<"GG"<<endl;
break;
}
if(isIn(i,y) && mp[i][y]=='B')
return;
}
//<<"TX: "<<tx<<" TY: "<<ty<<endl;
for(int i = tx-; i>=; i--) { //Up标记从找到的棋子到棋盘边缘的格子
// if(isIn(i,y) && (mp[i][y]==0 || mp[i][y]=='B')) {
res[i][y]=-;
//}
if(isIn(i,y) && mp[i][y]!= && mp[i][y]!='B'){//出现第二个格子就停止
break;
}
}
for(int i=y-; i>=; i--) { //Left
if(isIn(x,i) && mp[x][i]!= && mp[x][i]!='B') {
tx=x, ty = i;
break;
}
if(isIn(x,i) && mp[x][i]=='B'){
return;
}
}
for(int i=ty-; i>=; i--) { //Left
//if(isIn(x,i) && (mp[x][i]==0 || mp[x][i]=='B')) {
res[x][i] = -;
//}
if(isIn(x,i) && mp[x][i]== && mp[x][i]!='B'){
break;
}
}
for(int i = y+; i<=; i++) {//Right
if(isIn(x,i) && mp[x][i]!= && mp[x][i]!='B') {
tx = x,ty=i;
break;
}
if(isIn(x,i) && mp[x][i]=='B'){
return;
}
}
for(int i = y+; i<=; i++){//Right
//if(isIn(x,i) && (mp[x][i]==0 || mp[x][i]=='B')){
res[x][i] = -;
//}
if(isIn(x,i) && mp[x][i]== && mp[x][i]!='B'){
break;
}
}
} bool in(int x,int y){//判断黑棋是不是在规定的格子内部
if(x>= && x<= && y>= && y<=){
return true;
}
return false;
} bool judge(int x,int y){//判断有没有被将死
bool ok = false;
if(in(x-,y) && res[x-][y]!=-) ok = true;
if(in(x+,y) && res[x+][y]!=-) ok = true;
if(in(x,y-) && res[x][y-]!=-) ok = true;
if(in(x,y+) && res[x][y+]!=-) ok = true;
return ok;
} void check1(){
for(int i = ; i<=; i++){
for(int j = ; j<=; j++){
printf("%2d ",res[i][j]);
}
printf("\n");
}
} void check2(){
for(int i = ; i<=; i++){
for(int j = ; j<=; j++){
printf("%2d ",mp[i][j]);
}
printf("\n");
}
} int main() {
//FRE();scanf("%d%d%d",&N,&bx,&by)
//FRO();
while(cin>>N>>bx>>by) {//必须要吐槽一下,这里的输出太懵逼了,用scanf就出错,用cin就AC......
//printf("bx:%d by:%d\n",bx,by);
memset(mp,,sizeof(mp));
memset(res,,sizeof(res));
if(N==&&bx==&&by==) {
break;
}
mp[bx][by] = 'B';
char ch;
int rx,ry; for(int i = ; i<N; i++) {
getchar();
cin>>ch>>rx>>ry;
//scanf("%c %d %d",&ch,&rx,&ry);
//printf("ch:%c rx:%d ry:%d\n",ch,rx,ry);
mp[rx][ry] = ch;
t[i] = T{ch,rx,ry};
} for(int i = ; i<N; i++){
ch = t[i].ch;
rx = t[i].x;
ry = t[i].y;
if(ch=='R' || ch=='G') {
makeGR(rx,ry);
}
else if(ch=='H') {
makeH(rx,ry);
}
else if(ch=='C') {
makeC(rx,ry);
}
}
// check2();
// cout<<endl<<endl;
// check1();
if(judge(bx,by)){
printf("NO\n");
}else{
printf("YES\n");
}
}
return ;
}

UVA-1589 象棋(模拟)的更多相关文章

  1. UVA 1589:Xiangqi (模拟 Grade D)

    题目: 象棋,黑棋只有将,红棋有帅车马炮.问是否死将. 思路: 对方将四个方向走一步,看看会不会被吃. 代码: 很难看……WA了很多发,还越界等等. #include <cstdio> # ...

  2. UVA 1589 象棋

    题意: 给出一个黑方的将, 然后 红方有 2 ~ 7 个棋子, 给出摆放位置,问是否已经把黑将将死, 红方已经将军. 分析: 分情况处理, 车 马 炮, 红将情况跟车是一样的. 建一个数组board保 ...

  3. ●UVa 1589 Xiangqi(模拟)

    ●赘述题意 给出一个中国象棋残局,告诉各个棋子的位置,黑方只有1枚“将”,红方有至少2枚,至多7枚棋子,包含1枚“帅G”,和若干枚“车R”,“马H”,“炮C”.当前为黑方的回合,问黑方的“将”能否在移 ...

  4. 【每日一题】 UVA - 1589 Xiangqi 函数+模拟 wa了两天

    题意:背景就是象棋, 题解:坑点1(wa的第一天):将军可以吃掉相邻的棋子,(然行列也写反了orz) 坑点2(wa的第二天):将军到马要反过来写,边界有误,并且第一次碰到的车才算(写到后来都忘了) # ...

  5. UVA 246 - 10-20-30 (模拟+STL)

    UVA 246 - 10-20-30 题目链接 题意:给52张的扑克堆,先从左往右发7张牌,之后连续不断从左往右发7张牌,假设有牌堆形成了下面3种情况(按顺序推断): 1.头两张+尾一张和为10或20 ...

  6. UVa 11988 (数组模拟链表) Broken Keyboard (a.k.a. Beiju Text)

    题意: 模拟一个文本编辑器,可以输入字母数字下划线,如果遇到'['则认为是Home键,如果是']'则认作End键. 问最终屏幕上显示的结果是什么字符串. 分析: 如果在数组用大量的移动字符必然很耗时. ...

  7. uva 1589 by sixleaves

    坑爹的模拟题目.自己对于这种比较复杂点得模拟题的能力概述还不够,还多加练习.贴别是做得时候一直再想如何检查车中间有没有棋子,炮中间有没有棋子.到网上参考别人的代码才发先这么简单的办法,自己尽然想不到. ...

  8. UVa 1611 (排序 模拟) Crane

    假设数字1~i-1已经全部归位,则第i到第n个数为无序区间. 如果i在无序区间的前半段,那么直接将i换到第i个位置上. 否则先将i换到无序区间的前半段,再将i归位.这样每个数最多操作两次即可归位. # ...

  9. (1.1.9)UVA 10930 A-Sequence(模拟)

    /* * UVA_10930_1.cpp * * Created on: 2013年10月7日 * Author: Administrator */ #include <iostream> ...

  10. Uva - 1589 - Xiangqi

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

随机推荐

  1. JFreeChart生成饼形图(3)11 (转自 JSP开发技术大全)

    FreeChart生成饼形图(3) (转自 JSP开发技术大全) 14.3 利用JFreeChart生成饼形图 通过JFreeChart插件,即可以生成普通效果的饼形图,也可以生成3D效果的饼形图:如 ...

  2. 【NOIP1999】【Codevs 1046】旅行家的预算

    http://codevs.cn/problem/1046/ Solution: 贪心,如果当前油价很低,它就比起当前剩余油的价还低就可以替换,并且每次加满,最后把剩的油卖掉即可 油价用单调链表(不知 ...

  3. 【转载pku】三十分钟掌握STL

    三十分钟掌握STL 这是本小人书.原名是<using stl>,不知道是谁写的.不过我倒觉得很有趣,所以化了两个晚上把它翻译出来.我没有对翻译出来的内容校验过.如果你没法在三十分钟内觉得有 ...

  4. SVN主干与分支的合并 ***

    下面我将step by step地演示如何一次完整的branching和merging,包括创建分支.分支开发.分支和主线同步,分支合并到主线的全过程,甚至包括如何在本地创建一个测试用的reposit ...

  5. NOIP 2011 Mayan游戏 大暴搜

    题目链接:https://www.luogu.org/problemnew/show/P1312 我的第一篇题解!! 当然感谢ZAGER 的提示,他的链接https://www.cnblogs.com ...

  6. Helios Service Release 2安装SVN

    Eclipse Helios Service Release 2安装SVN地址:subclipse http://subclipse.tigris.org/update_1.6.x 1.使用方式:he ...

  7. E20180120-hm

    derive vt. 得到,导出; 源于,来自; (从…中) 提取; hierarchy  n. [计] 分层,层次; 等级制度; 统治集团; 天使的级别或等级; inheritance  n. 继承 ...

  8. 洛谷 P4180 【模板】严格次小生成树[BJWC2010]【次小生成树】

    严格次小生成树模板 算法流程: 先用克鲁斯卡尔求最小生成树,然后给这个最小生成树树剖一下,维护边权转点权,维护最大值和严格次大值. 然后枚举没有被选入最小生成树的边,在最小生成树上查一下这条边的两端点 ...

  9. $CF1153A\ Serval\ and\ Bus$

    看大佬的代码都好复杂(不愧是大佬\(orz\) 蒟蒻提供一种思路 因为求的是最近的车对吧\(qwq\) 所以我们可以用一个\(while\)循环所以没必要去用什么 \(for...\) 至于这是\(d ...

  10. [笔试面试题] 3-C++关键字篇

    C/C++关键字篇   语言是编程的基础,掌握基本的语言知识是编程的前提条件.关键字是组成语言的最基本单位,对关键字的理解,有助于编写高质量的代码. 1 static(静态)变量有什么作用? 在函数体 ...