UVa1589 坑點總結+參考代碼

題目大意:ios

  

  給出一個合乎規則的象棋殘局,棋盤上黑方只有將,紅方已經「delivered a check」。要求判斷紅方可否把黑方「checkmate」。c++

思路:函數

  1. 維護一個矩陣表示棋盤上紅方棋子的佈局;佈局

  2. 維護一個vector存儲紅方的棋子的位置,以便於後續訪問;測試

  3. 模擬黑將走一步的過程,對於每一個黑將可能走的位置,判斷黑將是否會被吃掉。若是全部能走的位置上黑將都會被吃掉,那麼輸出YES。若是存在一個位置使黑將逃脫,輸出NO。spa

 

坑點:code

  1. 黑將走到下一步時也能夠吃掉紅方。blog

  2. 雖然黑方在初始位置能夠不被吃,但此時已經輪到黑方走,黑將必須走一步,不能停在原地。假如全部能走到的地方都會被吃,黑方還是要輸的。ci

  3. 衆所周知,uDebug上的數據極可能是有坑的。it

 

 特別地,對比車和炮的規則發現,炮在行進路線上能且只能跳過1個棋子,而車在路線上不能跳棋子(即能跳0個棋子),除此以外,規則的其它部分是相同的。所以徹底能夠把車和炮封裝到同一函數chariot()上,惟一的區別在於能跳0仍是1個棋子,具體調用見第66行和71行的代碼。

 

AC代碼以下(C++)

  1 #include <bits/stdc++.h>
  2 #define N 11
  3 #define mp(x,y) make_pair(x,y)
  4 #define fi() first
  5 #define se() second
  6 using namespace std;
  7 char mat[N][N];
  8 vector<pair<int,int> > rds;
  9 const int mv[][2] = {{-1,0},{1,0},{0,1},{0,-1}};
 10 const int mv2[4][2][2] = {
 11     {{-1,-1},{-1,1}},
 12     {{1,-1},{1,1}},
 13     {{-1,1},{1,1}},
 14     {{-1,-1},{1,-1}}
 15 };
 16 
 17 //
 18 // 判斷車/炮(x,y)可否將黑將(bx,by)吃掉
 19 //
 20 inline bool chariot(int bx,int by, int x,int y, int cc) {
 21     int cnt=0;
 22     if(x==bx) {
 23         for(int i=min(by,y)+1; i<max(by,y); ++i) {
 24             if(mat[x][i] != 0) {
 25                 ++cnt;
 26             }
 27         }
 28         if(cnt==cc) return false;
 29     } else if (y==by) {
 30         for(int i=min(bx,x)+1; i<max(bx,x); ++i) {
 31             if(mat[i][y] != 0) {
 32                 ++cnt;
 33             }
 34         }
 35         if(cnt==cc) return false;
 36     }
 37     return true;
 38 }
 39 
 40 inline bool inbnd(int r, int c) {
 41     return !(r<1||r>10 || c<1||c>9);
 42 }
 43 
 44 //
 45 // 判斷黑將在(bx,by)上是否危險
 46 //
 47 bool judge(int bx, int by) {
 48     for(size_t i=0;i<rds.size();++i) {
 49         int x = rds[i].fi();
 50         int y = rds[i].se();
 51         if(x==bx&&y==by) continue;
 52         switch(mat[x][y]) {
 53             case 'G':
 54                 if(y==by) {
 55                     int i;
 56                     for(i=bx+1; i<x; ++i) {
 57                         if(mat[i][y] != 0) {
 58                             break;
 59                         }
 60                     }
 61                     if(i==x) return false;
 62                 }
 63                 break;
 64             case 'R':
 65                 if(x==bx || y==by) {
 66                     if(!chariot(bx,by,x,y, 0)) return false;
 67                 }
 68                 break;
 69             case 'C':
 70                 { 
 71                     if(!chariot(bx,by,x,y, 1)) return false;
 72                 } 
 73                 break;
 74             case 'H':
 75                 for(int i=0;i<4;++i) {
 76                     int nx1=x+mv[i][0], ny1=y+mv[i][1];
 77                     if(inbnd(nx1,ny1) && mat[nx1][ny1]==0 && nx1!=bx&&ny1!=by) {
 78                         for(int j=0;j<2;++j) {
 79                             int nx2=nx1+mv2[i][j][0], ny2=ny1+mv2[i][j][1];
 80                             if(nx2==bx && ny2==by) {
 81                                 return false;
 82                             }
 83                         }
 84                     } 
 85                 }
 86                 break;
 87         }
 88     }
 89     return true;
 90 }
 91 
 92 //
 93 // 求解單個測試用例
 94 //
 95 const char *solve(int bx, int by) {
 96     for(int i=0;i<4;++i) {
 97         int nx=bx+mv[i][0], ny=by+mv[i][1];
 98         if(nx<1||nx>3 || ny<4||ny>6) continue;
 99         if(judge(nx,ny)) {
100             return "NO";
101         }
102     }
103     return "YES";
104 }
105 
106 int main(void) {
107     ios::sync_with_stdio(false);
108     int n,xb,yb;
109     while((cin>>n>>xb>>yb) && (n&&xb&&yb))  {
110         memset(mat, 0, sizeof mat);
111         rds.clear();
112         
113         while(n--) {
114             char typ; int x,y;
115             cin>>typ>>x>>y;
116             mat[x][y] = typ;
117             rds.push_back(mp(x,y));
118         }
119         
120         cout<<solve(xb, yb)<<endl;
121     }
122     return 0;
123 }
相關文章
相關標籤/搜索