UVA 1589 Xiangqi (模拟)
1.可能当前状态是胜利的(直接飞将吃掉对面帅)
2.如果不是胜利的,检查四个方向,如果能移动的方向都是死,说明现在是必输状态
3.模拟各种死亡的条件,马,飞将,炮,车
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char g[11][10]; int bx,by;//黑将的位置 int r = 10; int c = 9; int GM[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};//将的移动方向 int HD[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//马相对于将的位置 int MJ[8][2] = {{-1,-1},{-1,1},{-1,1},{1,1},{1,1},{1,-1},{1,-1},{-1,-1}};//马脚相对于将的位置 bool isOut(int x,int y){//黑将是否出界 return !(x>=1&&x<=3&&y>=4&&y<=6); } bool isOut2(int x,int y){//马是否出界 return !(x>=1&&x<=r&&y>=1&&y<=c); } bool checkHorizontalFirst(int x,int y,char target){//横向是否能第一次遇见target int j; for(j=y-1;j>=1;j--) if(g[x][j]) if(g[x][j]==target) return true; else break; for(j=y+1;j<=c;j++) if(g[x][j]) if(g[x][j]==target) return true; else break; return false; } bool checkVerticalFirst(int x,int y,char target){//纵向是否能第一次遇见target int i; if(target!='G'){ for(i=x-1;i>=1;i--) if(g[i][y]) if(g[i][y]==target) return true; else break; } //如果检查飞将只需要向下查找就可以了 for(i=x+1;i<=r;i++) if(g[i][y]) if(g[i][y]==target) return true; else break; return false; } bool check1(int x,int y){//检查当前移动位置能否遇见车是否能遇见车 return checkHorizontalFirst(x,y,'R')||checkVerticalFirst(x,y,'R'); } bool check2(int x,int y){ //有没有飞将 return checkVerticalFirst(x,y,'G'); } bool check3(int x,int y){ //横纵向是否有炮 int cnt; int i,j; int t ; int i1,j1; for(i=1;i<=r;i++){//纵向 if(i!=x&&g[i][y]=='C'){ int a = x; int b = i; if(a>b){ t = a; a = b; b = t; } cnt = 0;//检查炮和将中间有多少子 for(i1 = a+1;i1<=b-1;i1++){ if(g[i1][y]){ cnt++; } } if(cnt==1) return true; } } for(j=1;j<=c;j++){ if(j!=y&&g[x][j]=='C'){ int a = y; int b = j; if(a>b){ t = a; a = b; b = t; } cnt = 0;//检查炮和将中间有多少子 for(j1 = a+1;j1<=b-1;j1++){ if(g[x][j1]){ cnt++; } } if(cnt==1) return true; } } return false; } bool check4(int x,int y){ int i; for(i=0;i<8;i++){ int nx = x + HD[i][0]; int ny = y + HD[i][1]; int nxx = x + MJ[i][0]; int nyy = y + MJ[i][1]; if(!isOut2(nx,ny)&&g[nx][ny]=='H'&&!g[nxx][nyy]){//这个位置没有出界,并且有马,而且没有别马脚 return true; } } return false; } bool check(int x,int y){ int cnt = 0; int dir = 0; int i; if(check2(x,y)) return false;//如果直接就能飞将杀死对面也就不需要检查死亡了。。。 for(i=0;i<4;i++){ int nx = x+GM[i][0]; int ny = y+GM[i][1]; if(!isOut(nx,ny)){ dir++; //当前移动方向上有东西,吃掉 char t = g[nx][ny]; g[nx][ny] = '\0'; if(check1(nx,ny)||check2(nx,ny)||check3(nx,ny)||check4(nx,ny)) cnt++; g[nx][ny] = t;//恢复图的状态 } } return dir==cnt; } int main() { int rnum,i,cx,cy; char cc; while(cin>>rnum>>bx>>by&&(rnum+bx+by)){ memset(g,0,sizeof(g)); for(i=0;i<rnum;i++){ cin>>cc>>cx>>cy; g[cx][cy] = cc; } bool flag = check(bx,by); if(flag) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }

浙公网安备 33010602011771号