UVa 1589 - Xiangqi <细节基础题>
2015-01-31 14:12
281 查看
这个题,三个月前写了一次,当时写道200行的时候,就感觉恶心了,当时感觉再写100行也完不成。
今天拿出这题来重写了,尽量精简代码,结果没想到90行就AC了。精简代码的好处之一便是方便调试,因为细节太多了,把很多相似的内容放在函数中就好了。
看似四个棋子的走法不同,实则有一个共同点:都需要判断棋子和“将”所在的行或者列中,两个棋子之间的棋子数。对于“帅”和“车”,之间的棋子数必须为0。对于炮,之间的棋子数必须为1。对于马,可以利用这一点判断是否有憋马脚的情况。
其他需要注意的点:
1.初始棋盘中,如果将帅正对,那么红方必败。
2.红方棋子有可能被将吃掉,需要处理。
今天拿出这题来重写了,尽量精简代码,结果没想到90行就AC了。精简代码的好处之一便是方便调试,因为细节太多了,把很多相似的内容放在函数中就好了。
看似四个棋子的走法不同,实则有一个共同点:都需要判断棋子和“将”所在的行或者列中,两个棋子之间的棋子数。对于“帅”和“车”,之间的棋子数必须为0。对于炮,之间的棋子数必须为1。对于马,可以利用这一点判断是否有憋马脚的情况。
其他需要注意的点:
1.初始棋盘中,如果将帅正对,那么红方必败。
2.红方棋子有可能被将吃掉,需要处理。
#include <bits/stdc++.h> using namespace std; struct One{ int r, c; char type; }; One Red[10]; int N, r0, c0, G_NO; char tab[12][12]; const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; const int Hdir[8][4] = { {-1, 2, 0, 2}, {1, 2, 0, 2}, {-2, -1, -2, 0}, {-2, 1, -2, 0}, {-1, -2, 0, -2}, {1, -2, 0, -2}, {2, -1, 2, 0}, {2, 1, 2, 0} }; inline bool in_black_palace(const int r, const int c){ return r >= 1 && r <= 3 && c >= 4 && c <= 6; } int get_range_block(int r1, int c1, int r2, int c2){ int cnt = 0; if(r1 != r2 && c1 != c2) return -1; if(r1 == r2){ if(c1 > c2) swap(c1, c2); for(int i = c1 + 1; i <= c2 - 1; ++i) if(tab[r1][i] != '\0') cnt++; } else if(c1 == c2){ if(r1 > r2) swap(r1, r2); for(int i = r1 + 1; i <= r2 - 1; ++i) if(tab[i][c1] != '\0') cnt++; } return cnt; } bool G(const int r, const int c, const int x, const int y){ if(c != y) return false; return get_range_block(r, c, x, y) == 0; } bool R(const int r, const int c, const int x, const int y){ int res = get_range_block(r, c, x, y); if(res == -1) return false; return res == 0; } bool H(const int r, const int c, const int x, const int y){ for(int i = 0; i < 8; ++i){ int x1 = x + Hdir[i][0], y1 = y + Hdir[i][1]; if(x1 == r && y1 == c && get_range_block(x, y, x + Hdir[i][2], y + Hdir[i][3])==0) return true; } return false; } bool C(const int r, const int c, const int x, const int y){ int res = get_range_block(r, c, x, y); if(res == -1) return false; return res == 1; } bool check_red_win(const int r, const int c){ for(int i = 0; i < N; ++i) if(!(Red[i].r==r && Red[i].c==c)){ One & t = Red[i]; if(t.type == 'G' && G(r, c, t.r, t.c)) return true; if(t.type == 'R' && R(r, c, t.r, t.c)) return true; if(t.type == 'H' && H(r, c, t.r, t.c)) return true; if(t.type == 'C' && C(r, c, t.r, t.c)) return true; } return false; } int main() { ios::sync_with_stdio(false); while(memset(Red, 0, sizeof(Red)), memset(tab, 0, sizeof(tab)), cin >> N >> r0 >> c0, !(N==0 && r0==0 && c0==0)){ for(int i = 0; i < N; i++){ One t; cin >> t.type >> t.r >> t.c; if(t.type=='G') G_NO = i; tab[t.r][t.c] = t.type; Red[i] = t; } if(G(r0, c0, Red[G_NO].r, Red[G_NO].r)) {puts("NO"); continue;} bool red_win = true; for(int i = 0; i < 4; ++i){ int r1 = r0 + dir[i][0], c1 = c0 + dir[i][1]; if(in_black_palace(r1, c1) && !check_red_win(r1, c1)) {red_win = false; break;} } if(red_win) puts("YES"); else puts("NO"); } return 0; }
相关文章推荐
- UVa 1589 - Xiangqi <细节基础题>
- C#基础学习日志===>二维数组<===
- cocos2d-x基础<四> Action
- cocos2d-x基础<一> Android环境配置和HelloWorld的运行
- cocos2d-x基础<三> 播放动画
- Java 基础一些代码练习笔记( GenericFoo<T> 泛型2)
- C#基础学习日志===&amp;amp;amp;amp;gt;命名空间的使用&amp;amp;amp;amp;lt;===
- C语言常见错误分析(基础细节面试点之一)<转摘>
- Java 基础一些代码练习笔记( GenericFoo<T> 泛型)
- [置顶]Emacs for vi Users | Emacs 和 Vim 基础键对应 ----<编辑器基础操作, buffer操作>
- 原创:oracle PL/SQL编程基础 上<十一>
- html基础学习一:html文件中的头部文件部分<head></head>
- &lt;展现C#&gt;第二章NGWSRuntime技术基础
- C#基础学习日志===&amp;gt;Method&amp;lt;===
- C#基础学习日志===&gt;数组&lt;===
- [置顶]Emacs for vi Users | Emacs 和 Vim 基础键对应 ----<编辑器文本操作,搜索/替换/正则操作>
- IM 开源项目 登录服务器 基础表结构<2>
- Nullable<>基础应用
- html系统学习之一<基础知识,标签,元素>
- 《Windows程序设计》读书笔记------------->>GDI的简单基础<<