题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4121
康复训练
小模拟
几个坑:
1.黑general可以通过飞过来吃掉红general来摆脱困境
2.可能需要注意某些棋子被黑general吃掉的情况
本质是搜索 这种题完全不可能卡时间
将、车、炮用一种判法
马另用一种判法
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <cmath> #include <set> #include <queue> #include <stack> #include <map> #include <vector> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; int xx, yy;//敌军将帅原始位置 int rcnt, ccnt, hcnt, gcnt; int r[10][2]; int c[10][2]; int h[10][2]; int g[10][2]; int board[12][11]; int hboard[12][11]; const int walk[4][2] = {1, 0, 0, 1, -1, 0, 0, -1}; const int hwalk[8][2] = {2, 1, 1, 2, -1, 2, -2, 1, -1, -2, -2, -1, 1, -2, 2, -1}; const int hcheck[4][2] = {1, 1, -1, 1, -1, -1, 1, -1}; int lineCheck(int a, int b, int mode, int k) { int cnt = 0; if(a > b) swap(a, b); for(int i = a+1; i < b; i++) { if(mode == 0) { if(board[k][i] == 1) cnt++; } else if(mode == 1) { if(board[i][k] == 1) cnt++; } } return cnt; } bool check(int x, int y) { for(int i = 0; i < gcnt; i++) { if(g[i][1] == y) { if(lineCheck(x, g[i][0], 1, y) == 0) return true; } } for(int i = 0; i < rcnt; i++) { if(r[i][0] == x && !(r[i][0] == x && r[i][1] == y)) { if(lineCheck(r[i][1], y, 0, x) == 0) return true; } else if(r[i][1] == y && !(r[i][0] == x && r[i][1] == y)) { if(lineCheck(r[i][0], x, 1, y) == 0) return true; } } for(int i = 0; i < ccnt; i++) { if(c[i][0] == x && !(c[i][0] == x && c[i][1] == y)) { if(lineCheck(c[i][1], y, 0, x) == 1) return true; } else if(c[i][1] == y && !(c[i][0] == x && c[i][1] == y)) { if(lineCheck(c[i][0], x, 1, y) == 1) return true; } } for(int i = 0; i < 8; i++) { int a = x + hwalk[i][0]; int b = y + hwalk[i][1]; if(1 <= a && a <= 10 && 1 <= b && b <= 9) { if(hboard[a][b] == 1) { int aa = x + hcheck[i/2][0]; int bb = y + hcheck[i/2][1]; if(board[aa][bb] == 0)//判绊马脚 return true; } } } return false; } int main() { //freopen("in.txt", "r", stdin); int n; char buf[10]; while(scanf("%d%d%d", &n, &xx, &yy) == 3 && n != 0) { memset(board, 0, sizeof(board)); memset(hboard, 0, sizeof(hboard)); rcnt = 0; ccnt = 0; hcnt = 0; gcnt = 0; int tmpx, tmpy; for(int i = 0; i < n; i++) { scanf("%s%d%d", buf, &tmpx, &tmpy); board[tmpx][tmpy] = 1; if(buf[0] == 'G') { g[gcnt][0] = tmpx; g[gcnt][1] = tmpy; gcnt++; } else if(buf[0] == 'R') { r[rcnt][0] = tmpx; r[rcnt][1] = tmpy; rcnt++; } else if(buf[0] == 'C') { c[ccnt][0] = tmpx; c[ccnt][1] = tmpy; ccnt++; } else if(buf[0] == 'H') { hboard[tmpx][tmpy] = 1; h[hcnt][0] = tmpx; h[hcnt][1] = tmpy; hcnt++; } } bool flag = true; if(yy == g[0][1]) { if(lineCheck(xx, g[0][0], 1, yy) == 0) { printf("NO "); continue; } } for(int i = 0; i < 4; i++) { int x = xx + walk[i][0]; int y = yy + walk[i][1]; if(1 <= x && x <= 3 && 4 <= y && y <= 6) { flag = check(x, y); } if(!flag) break; } if(flag) printf("YES "); else printf("NO "); } return 0; }
一开始写得急 边写边想
然后就搞得里面有很多代码块有重复 但却懒得去重构 心想过了就好
然后改来改去还是wa
最后试着把重复的代码块抽出来写了一个lineCheck函数就过了
模拟题还是不能懒
特别要注意如果有重复的代码块最好另起一个函数
一是只需要写一次 出错的机会小了
二是如果发现错了 也好改 就改一处 不会有什么改漏了改串了的情况