这道题是一道模拟题,就是用来判断黑的一方能不能存活,所以就将黑的将军所有合法的移动情况都表示出来,看一看黑将军是否被红的将军,就可以了,主要注意的以下几点:
1、如果黑的能够直接杀死红的,那就输出 NO
2、蹩马腿的情况
3、不要越界
不过这些能够避免却仍然不能AC,为啥?下面就来聊一聊那些细节。
#include <stdio.h> int main() { int a = 5; if(a > 10) if(a > 15) printf("1"); else printf("2"); return 0; }
这个输出会是多少呢?
可能是“2”?,那你就大错特错了,不会输出任何东西,你认为else 与 第一个 if 是并列的, 然而与第二个是并列的, 将 a 的值改为 14, 输出的答案是 2 , 所以 else 只和离他最近的 if 并列,那么怎么解决这种问题呢? 打个括号就行了。
#include <stdio.h> int main() { int a = 5; if(a > 10) { if(a > 15) printf("1"); } else printf("2"); return 0; }
这样就输出“2”了,所以在写程序时一定要注意这些问题, 否则有时debug半天然后一无所获。
下面就说一说另一个问题,在读入红方的身份时,用getchar() + scanf("%c" .. 要不如 scanf("%s", s) 好, 严格来说这两种方法都行,但是面对不严谨的出题时候,用scanf(“%s", s)确实正确的,而getchar() + scanf("%c")就不行, 这道题就是这样,我们将这种情况称为鲁棒性(robustness),如果鲁棒性好的程序,会在有瑕疵数据的清狂下仍然输出正确的结果,所以写鲁棒性好的程序会加快效率,让我们得到令人惊喜的结果。
就主要注意这两点吧!
下面是我写的代码,不长也不短,争取以后要写出短小而精悍的代码,这需要丰富我的经验与大脑。
//#define LOCAL #include <stdio.h> #include <string.h> //use memset int chess[15][15]; int X, Y, B; int G(int x, int y) { for(int i = x+1; i <= 10; i++) { if(chess[i][y] == 'G'-'A') return 1; if(chess[i][y] != 0) return 0; } } int C_R(int a, int b, int x, int y, int p) //0 -> C 1 -> R { int cnt = 0; if(a == x) { if(b < y) { for(int i = b+1; i < y; i++) if(chess[x][i] != 0) cnt++; } else { for(int i = y+1; i < b; i++) if(chess[x][i] != 0) cnt++; } } else { if(a < x) { for(int i = a+1; i < x; i++) if(chess[i][y] != 0) cnt++; } else { for(int i = x+1; i < a; i++) if(chess[i][y] != 0) cnt++; } } if(!p) { if(cnt == 1) return 1; return 0; } if(!cnt) return 1; return 0; } int H(int a, int b, int x, int y) { if(a+1 <= 10 && !chess[a+1][b] && ((a+2 == x && b-1 == y) || (a+2 == x && b+1 == y))) return 1; if(a-1 > 0 && !chess[a-1][b] && ((a-2 == x && b-1 == y) || (a-2 == x && b+1 == y))) return 1; if(b+1 <= 9 && !chess[a][b+1] && ((a-1 == x && b+2 == y) || (a+1 == x && b+2 == y))) return 1; if(b-1 > 0 && !chess[a][b-1] && ((a-1 == x && b-2 == y) || (a+1 == x && b-2 == y))) return 1; return 0; } int Try(int x, int y) { for(int i = 1; i <= 10; i++) for(int j = 1; j <= 9; j++) if(chess[i][j] != 0 && !(i == x && j == y)) { if(chess[i][j] == 'G'-'A' && j == y && G(x, y)) return 0; if(chess[i][j] == 'C'-'A' && (i == x || j == y) && C_R(i, j, x, y, 0)) return 0; if(chess[i][j] == 'R'-'A' && (i == x || j == y) && C_R(i, j, x, y, 1)) return 0; if(chess[i][j] == 'H'-'A' && H(i, j, x, y)) return 0; } return 1; } int check() { if(B == Y && G(X, Y)) return 0; if(X+1 < 4 && Try(X+1, Y)) return 0; if(X-1 > 0 && Try(X-1, Y)) return 0; if(Y+1 < 7 && Try(X, Y+1)) return 0; if(Y-1 > 3 && Try(X, Y-1)) return 0; return 1; } int main() { // #ifdef LOCAL // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); // #endif int n, x, y; char a[5]; while(scanf("%d%d%d", &n, &x, &y) == 3 && n != 0) { X = x; Y = y; memset(chess, 0, sizeof(chess)); for(int i = 0; i < n; i++) { scanf("%s%d%d", a, &x, &y); if(a[0] == 'G') B = y; chess[x][y] = a[0]-'A'; } if(check()) printf("YES "); else printf("NO "); } return 0; }