●UVa 1589 Xiangqi(模拟)
●赘述题意
给出一个中国象棋残局,告诉各个棋子的位置,黑方只有1枚“将”,红方有至少2枚,至多7枚棋子,包含1枚“帅G”,和若干枚“车R”,“马H”,“炮C”。当前为黑方的回合,问黑方的“将”能否在移动一步后不被“将军”。
●题解
本题就是一个模拟:枚举“将”向四个方向走,是否满足题意。
但比较考察逻辑和代码能力。
但有一个坑点:
“将”在移动时,不能移动到与“帅”照面。
但,恶心的数据会有输入的局面就出现将帅照面的情况,按理说,应是黑方赢了(因为轮到黑方的回合),也就是说在程序中加一个特判。但不需要这么做,或者说:不需要我们这样处理,黑“将”不能在这种情况下直接向“帅”“开大炮”…
●代码(没用网上的二维数组的方法,是直接枚举红棋判断)
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int mv[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; const int hv[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}}; const int hp[8][2]={{-1,0},{0,1},{0,1},{1,0},{1,0},{0,-1},{0,-1},{-1,0}}; struct node{ char ch; int x,y; }a[10]; int n; int abs(int x) { return x>0?x:-x; } bool eat(int bx,int by,int p) { return bx==a[p].x&&by==a[p].y; } bool CRkill(int bx,int by,int p,int t) { if(a[p].x!=bx&&a[p].y!=by) return 0; int fg=a[p].y==by,l,r,cnt=0; if(!fg) l=min(a[p].y,by),r=max(a[p].y,by); else l=min(a[p].x,bx),r=max(a[p].x,bx); for(int i=1;i<=n;i++) if(i!=p&&!eat(bx,by,i)) { if(!fg&&a[i].x==bx&&l<a[i].y&&a[i].y<r) cnt++; if(fg&&a[i].y==by&&l<a[i].x&&a[i].x<r) cnt++; } return cnt==t; } bool Hkill(int bx,int by,int p) { if(abs(bx-a[p].x)*abs(by-a[p].y)!=2) return 0; int fx,fy; for(int i=0;i<8;i++) { fx=a[p].x+hv[i][0]; fy=a[p].y+hv[i][1]; if(fx==bx&&fy==by) { bool fg=1; for(int j=1;j<=n;j++) if(j!=p&&!eat(bx,by,j)) if(a[j].x==a[p].x+hp[i][0]&&a[j].y==a[p].y+hp[i][1]) fg=0; if(fg) return 1; } } return 0; } bool live(int bx,int by) { for(int i=1;i<=n;i++) if(!eat(bx,by,i)) { if(a[i].ch=='G'&&CRkill(bx,by,i,0)) return 0; if(a[i].ch=='R'&&CRkill(bx,by,i,0)) return 0; if(a[i].ch=='C'&&CRkill(bx,by,i,1)) return 0; if(a[i].ch=='H'&&Hkill(bx,by,i)) return 0; } return 1; } bool check(int bx,int by) { int fx,fy; for(int i=0;i<4;i++) { fx=bx+mv[i][0]; fy=by+mv[i][1]; if(fx<1||fx>3||fy<4||fy>6) continue; if(live(fx,fy)) return 0; } return 1; } int main() { int bx,by; while(1) { cin>>n>>bx>>by; if(!n&&!bx&&!by) break; for(int i=1;i<=n;i++) cin>>a[i].ch>>a[i].x>>a[i].y; if(check(bx,by)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
Do not go gentle into that good night.
Rage, rage against the dying of the light.
————Dylan Thomas