HDU 4121 Xiangqi (算是模拟吧)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4121
题意:中国象棋对决,黑棋只有一个将,红棋有一个帅和不定个车 马 炮冰给定位置,这时当黑棋走,问你黑棋是不是被将死了(当前位置被将,能走得下一步也被将)
题解:代码里面注释很详细,我就不多说了,知道象棋规则的同学基本上都可以做出来
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <deque> #include <queue> #include <iterator> #include <stack> #include <map> #include <set> #include <algorithm> #include <cctype> using namespace std; #define si1(a) scanf("%d",&a) #define si2(a,b) scanf("%d%d",&a,&b) #define sd1(a) scanf("%lf",&a) #define sd2(a,b) scanf("%lf%lf",&a,&b) #define ss1(s) scanf("%s",s) #define pi1(a) printf("%d\n",a) #define pi2(a,b) printf("%d %d\n",a,b) #define mset(a,b) memset(a,b,sizeof(a)) #define forb(i,a,b) for(int i=a;i<b;i++) #define ford(i,a,b) for(int i=a;i<=b;i++) typedef long long LL; const int N=110001; const int M=1000007; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-7; char mp[11][11]; int bx,by,n; int tt[4][2]={1,0,-1,0,0,1,0,-1}; struct node { int x,y; }pp[11]; bool shu(int x1,int x2,int y) { if(x1>x2) swap(x1,x2); int f=0; for(int i=x1+1;i<x2;i++) if(mp[i][y]!='0') f=1; if(f) return false; else return true; } bool heng(int x,int y1,int y2) { if(y1>y2) swap(y1,y2); int f=0; for(int j=y1+1;j<y2;j++) if(mp[x][j]!='0') f=1; if(f) return false; else return true; } bool shuone(int x1,int x2,int y) { if(x1>x2) swap(x1,x2); int f=0; for(int i=x1+1;i<x2;i++) if(mp[i][y]!='0') f++; if(f!=1) return false; else return true; } bool hengone(int x,int y1,int y2) { if(y1>y2) swap(y1,y2); int f=0; for(int j=y1+1;j<y2;j++) if(mp[x][j]!='0') f++; if(f!=1) return false; else return true; } bool jiang(int x,int y) { forb(i,0,n) { int rx=pp[i].x,ry=pp[i].y; char c=mp[rx][ry]; if(c=='G')//对将的时候,判断在一列且中间没有棋子 { if(ry==y&&shu(x,rx,y)) return true; } if(c=='R')//车,判断在一行一列且中间没有棋子 { if(x==rx&&heng(x,y,ry)) return true; if(y==ry&&shu(x,rx,y)) return true; } if(c=='H')//马,判断距离为3,且没有被撇马腿 { if((abs(x-rx)+abs(y-ry))!=3) continue; if(abs(x-rx)==2) { if(rx<x&&mp[rx+1][ry]=='0') return true; if(rx>x&&mp[rx-1][ry]=='0') return true; } if(abs(y-ry)==2) { if(ry<y&&mp[rx][ry+1]=='0') return true; if(ry>y&&mp[rx][ry-1]=='0') return true; } } if(c=='C')//炮,判断在一行一列且中间只有一个棋子 { if(x==rx&&hengone(x,y,ry)) return true; if(y==ry&&shuone(x,rx,y)) return true; } } return false; } int main() { while(scanf("%d%d%d",&n,&bx,&by)&&(n+bx+by)!=0) { memset(mp,'0',sizeof(mp)); char c; int x,y; forb(i,0,n) { cin>>c>>x>>y; mp[x][y]=c; pp[i].x=x; pp[i].y=y; } if(!jiang(bx,by))//如果开始的时候都不将军则直接输出no { printf("NO\n"); continue; } int flag=0; forb(i,0,4)//可以向四个方向走 { x=bx+tt[i][0]; y=by+tt[i][1]; if(x>=1&&x<=3&&y>=4&&y<=6)//注意范围 { char c=mp[x][y];//这个地方要注意,如果有棋子的话可以吃,开始的时候我认为有棋子的地方不能走 mp[x][y]='0'; if(!jiang(x,y))//判断能不能将军 { flag=1; break; } mp[x][y]=c;//还原 } } printf("%s\n",flag?"NO":"YES"); } return 0; }