Uva 1589 - Xiangqi (模拟)
题意:
考虑一个象棋残局,其中红方有n(2<=n<=7)个棋子,黑方只有一个将。红方除了有一个帅(G)以外还有3种
可能的棋子:车(R)、马(H)、炮(C),并且需要考虑“蹩马腿”与将和帅不能照面(将、帅如果同在一条直
线上,中间又不隔着任何棋子的情况下,走子的一方获胜)的规则。
输入所有棋子的位置,保证局面合法并且红方已经将军。判断红方是否已经把黑方将死。
思路:
将死,即黑方的将所在的地方和上下左右都不能走了。
把红方的每个棋子能杀的地方标记,判断 黑方将是否还有能走的地方,如果有则没将死。
注意这其中,黑方将上下左右有棋子它是可以吃掉的。
为了清楚的标记且避免在原数组上改动造成对结果的影响,另开一个vis数组标记。
最开始我是在原数组上标记,如果是不能走的就标为-1。但是如果这里不考虑这个位置原来有没有棋子就标,
会减少能控制的位置,因为标为-1的棋子就不能判断它是否有可以杀的位置。如果考虑到这点进行判断,如
果有棋子就不标为-1,则由于黑方将只要能走就可以吃掉有子的位置,所以当能吃掉这颗棋子的时候,由于
没有标为-1,就得到了错误的结果。如果把这个位置先判断再改为0,再判断其他位置,在判断蹩腿马的时候
会出现错误。蹩腿的位置本来有棋子,但是先判断该棋子后改为标记0了,这时候马就由蹩腿改为不蹩腿了。
综上,在原数组上标记会导致错误。故最好令开标记数组,反正数组空间也不大。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cctype> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #include<set> 12 #define eps 10e-6 13 14 using namespace std; 15 16 typedef long long ll; 17 18 int mp[12][12]; 19 bool vis[12][12]; 20 vector<pair<int,int> > pos; 21 vector<pair<int,int> > obj; 22 //G=1 R=2 H=3 C=4 23 int bx,by; 24 25 void check(int x,int y,int type) 26 { 27 if(type == 1 || type == 2 || type == 4) 28 { 29 for(int i=0;i<obj.size();i++) 30 { 31 int ox = obj[i].first; 32 int oy = obj[i].second; 33 // cout<<"ox="<<ox<<' '<<"oy="<<oy<<endl; 34 if(ox==x && oy==y) continue; 35 if(ox==x) 36 { 37 int disy = oy - y>0?1:-1; 38 int cnt = 0; 39 for(int i=y+disy;i!=oy;i+=disy) 40 { 41 if(mp[ox][i]>0) 42 cnt++; 43 } 44 if((cnt==0 && type == 1) ||(cnt==0 && type==2) || (cnt==1 && type==4)) 45 vis[ox][oy] = true; 46 } 47 else if(oy == y) 48 { 49 int disx = ox - x>0?1:-1; 50 int cnt = 0; 51 for(int i=x+disx;i!=ox;i+=disx) 52 { 53 if(mp[i][oy]>0) 54 cnt++; 55 } 56 if((cnt==0 && type == 1) ||(cnt==0 && type==2) || (cnt==1 && type==4)) 57 vis[ox][oy] = true; 58 } 59 } 60 } 61 else if(type == 3) 62 { 63 if(x-1>0 && mp[x-1][y]<=0) 64 { 65 if(x-2>0 && y-1>0) vis[x-2][y-1] = true; 66 if(x-2>0 && y+1<=10) vis[x-2][y+1] = true; 67 } 68 if(x+1<=10 && mp[x+1][y]<=0) 69 { 70 if(x+2<=10 && y-1>0) vis[x+2][y-1] = true; 71 if(x+2<=10 && y+1<=10) vis[x+2][y+1] = true; 72 } 73 if(y-1>0 && mp[x][y-1]<=0) 74 { 75 if(x-1>0 && y-2>0) vis[x-1][y-2] = true; 76 if(x+1<=10 && y-2>0) vis[x+1][y-2] = true; 77 } 78 if(y+1<=10 && mp[x][y+1]<=0) 79 { 80 if(x-1>0 && y+2<=10) vis[x-1][y+2] = true; 81 if(x+1<=10 && y+2<=10) vis[x+1][y+2] = true; 82 } 83 } 84 } 85 int xx[] = {-1,1,0,0}; 86 int yy[] = {0,0,-1,1}; 87 void init() 88 { 89 obj.push_back(make_pair(bx,by)); 90 for(int i=0;i<4;i++) 91 { 92 int nx = bx+xx[i]; 93 int ny = by+yy[i]; 94 if(nx>=1 && nx<=3 && ny>=4 && ny<=6) 95 obj.push_back(make_pair(nx,ny)); 96 } 97 } 98 99 int main() 100 { 101 char s[5]; 102 int n,x,y; 103 while(~scanf("%d%d%d",&n,&bx,&by) && n && bx && by) 104 { 105 pos.clear(); 106 obj.clear(); 107 memset(mp,0,sizeof(mp)); 108 memset(vis,0,sizeof(vis)); 109 110 for(int i=0;i<n;i++) 111 { 112 scanf("%s%d%d",s,&x,&y); 113 if(s[0]=='G') 114 mp[x][y] = 1; 115 else if(s[0]=='R') 116 mp[x][y] = 2; 117 else if(s[0]=='H') 118 mp[x][y] = 3; 119 else mp[x][y] = 4; 120 pos.push_back(make_pair(x,y)); 121 } 122 init(); 123 for(int i=0;i<pos.size();i++) 124 { 125 int nx,ny; 126 nx = pos[i].first; 127 ny = pos[i].second; 128 check(nx,ny,mp[nx][ny]); 129 } 130 int flag = 0; 131 for(int i=0;i<obj.size();i++) 132 { 133 int a = obj[i].first; 134 int b = obj[i].second; 135 if(!vis[a][b]) 136 { 137 flag = 1; 138 break; 139 } 140 } 141 if(!flag) puts("YES"); 142 else puts("NO"); 143 } 144 return 0; 145 } 146 147 /* 148 149 3 1 4 150 C 5 4 151 H 3 4 152 C 2 2 153 154 */ 155 156 /* 157 158 2 1 4 159 G 10 5 160 R 2 4 161 162 */