题意: 给一个象棋局势,问黑棋是否死棋了,黑棋只有一个将,红棋可能有2~7个棋,分别可能是车,马,炮以及帅。
解法: 开始写法是对每个棋子,都处理处他能吃的地方,赋为-1,然后判断将能不能走到非-1的点。但是WA了好久,也找不出反例,但就是觉得不行,因为可能有将吃子的情况,可能有hack点。但是比赛后还是被我调出来了。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; #define N 1017 int chess[14][13],mp[14][13]; //0 : Non 1:G帅 2:R车 3:H Horse 4:C Cannon int dx[4] = {0,-1,0,1}; int dy[4] = {1,0,-1,0}; bool InPalace(int nx,int ny) { if(nx >= 1 && nx <= 3 && ny >= 4 && ny <= 6) return true; return false; } bool InChess(int nx,int ny) { if(nx >= 1 && nx <= 10 && ny >= 1 && ny <= 9) return true; return false;} int main() { int n,X,Y,i,j,k; int x,y; char ss[4]; while(scanf("%d%d%d",&n,&X,&Y)!=EOF && (n+X+Y)) { memset(chess,0,sizeof(chess)); memset(mp,0,sizeof(mp)); for(i=1;i<=n;i++) { //0 : Non 1:G帅 2:R车 3:H Horse 4:C Cannon scanf("%s%d%d",ss,&x,&y); if(ss[0] == 'G') chess[x][y] = 1; else if(ss[0] == 'R') chess[x][y] = 2; else if(ss[0] == 'H') chess[x][y] = 3; else if(ss[0] == 'C') chess[x][y] = 4; } for(i=1;i<=10;i++) { for(j=1;j<=9;j++) { if(chess[i][j] == 1) // shuai { for(k=i-1;k>=1;k--) { if(chess[k][j] != 0) { mp[k][j] = -1; break; } if(k <= 3 && chess[k][j] == 0) mp[k][j] = -1; } } else if(chess[i][j] == 2) // R che { for(int D=0;D<4;D++) { int kx = i, ky = j; while(1) { kx = kx + dx[D]; ky = ky + dy[D]; if(!InChess(kx,ky)) break; if(chess[kx][ky] == 0) mp[kx][ky] = -1; else { mp[kx][ky] = -1; break; } } } } else if(chess[i][j] == 3) //Horse { if(InChess(i-1,j) && chess[i-1][j] == 0 && (i-1 != X || j != Y)) //UP not blocked { if(InChess(i-2,j-1)) mp[i-2][j-1] = -1; if(InChess(i-2,j+1)) mp[i-2][j+1] = -1; } if(InChess(i+1,j) && chess[i+1][j] == 0 && (i+1 != X || j != Y)) //DOWN not blocked { if(InChess(i+2,j-1)) mp[i+2][j-1] = -1; if(InChess(i+2,j+1)) mp[i+2][j+1] = -1; } if(InChess(i,j+1) && chess[i][j+1] == 0 && (i != X || j+1 != Y)) //RIGHT not blocked { if(InChess(i-1,j+2)) mp[i-1][j+2] = -1; if(InChess(i+1,j+2)) mp[i+1][j+2] = -1; } if(InChess(i,j-1) && chess[i][j-1] == 0 && (i != X || j-1 != Y)) //LEFT not blocked { if(InChess(i-1,j-2)) mp[i-1][j-2] = -1; if(InChess(i+1,j-2)) mp[i+1][j-2] = -1; } } else if(chess[i][j] == 4) //Cannon pao { for(int D=0;D<4;D++) { int kx = i, ky = j; int cnt = 0; while(1) { kx = kx + dx[D]; ky = ky + dy[D]; if(!InChess(kx,ky)) break; if(cnt == 1 && chess[kx][ky] == 0) mp[kx][ky] = -1; if(chess[kx][ky] != 0) { if(cnt == 0) cnt++; else if(cnt == 1) { mp[kx][ky] = -1; break; } } } } } } } int tag = 0; for(k=0;k<4;k++) { int kx = X + dx[k]; int ky = Y + dy[k]; if(!InChess(kx,ky) || !InPalace(kx,ky)) continue; if(mp[kx][ky] != -1) { tag = 1; break; } //可以走 } if(tag) puts("NO"); else puts("YES"); } return 0; }