TakeoffYoung

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

选拔赛(2)简单的状态压缩+bfs

屌洋直接用8维数组过的...代码美的一逼

 

题意:

  悟空(K)找唐僧(T),只能上下左右四个方向走,每步花费一个时间,碰到蛇精(S)需要额外花费一个时间去消灭,需要按照顺序(1, 2 ... k)搜集K把钥匙才能打开唐僧所在的房间。

 

总结:

  在读入矩阵的时候,把每个S换成其他的字符,比如(a, b, c...),这样再bfs的时候,碰到蛇精所在房间就可以直接判断当前蛇是否已经被杀死

  任何题目中bfs的时候不能修改原有的矩阵数据,(后来的节点还会走到这个点上)

  

if(a & b == 0){...}

if((a&b) == 0){...}

  下面的表达式才能正确判断,运算符优先级(可以在任何时候都把位运算放在括号里面)

  

  1 #include <bits/stdc++.h>
  2 
  3 const int MAXN = 100+5;
  4 
  5 int n, k;
  6 char ma[MAXN][MAXN];
  7 // state compression
  8 // the binary format of 31 is 11111
  9 // there are at most 5 snakes in the maze
 10 // so just use a binary digit bit to mark 
 11 // weather it has been visited or not
 12 // e.g. when wukong kills sankes numbered 1, 2, 5
 13 // the statement will be 10011(19)
 14 
 15 bool vis[MAXN][MAXN][10][32];
 16 
 17 // for direction Wukong can go
 18 int dir[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
 19 
 20 struct QueNode
 21 {
 22     int x, y, k, s, t;
 23     QueNode(){}
 24     // k is the number of keys wukong has 
 25     // s is the states of snakes (detail is the descriptioni of 'vis' above )
 26     // t is the time
 27     QueNode(int _x, int _y, int _k, int _s, int _t):x(_x), y(_y), k(_k), s(_s), t(_t){}
 28 
 29 };
 30 
 31 std::queue<QueNode> que;
 32 
 33 int main()
 34 {
 35 
 36     // this code below will clutter the output
 37     /* std::ios::sync_with_stdio(false); */
 38     
 39     while(std::cin >> n >> k && (n||k)){
 40 
 41         // init the variable
 42         // the efficient way to clear a std::queue
 43         // just create a empty_que and swap it with original queue
 44         memset(ma, '#', sizeof ma);
 45         memset(vis, false, sizeof vis);
 46         std::queue<QueNode> empty_que;
 47         std::swap(que, empty_que);
 48 
 49         // the highlight point 
 50         // dealing with the snakes 
 51         // rename it to enable it to show which snake it is
 52         int snake_num = 0; 
 53         
 54         for(int i = 1; i <= n; ++ i){
 55             for(int j = 1; j <= n; ++ j){
 56                 std::cin >> ma[i][j];
 57                 if(ma[i][j] == 'S'){
 58                     ma[i][j] = (++snake_num) + 'a';
 59                 }
 60                 if(ma[i][j] == 'K'){
 61                     que.push(QueNode(i, j, 0, 0, 0));
 62                     vis[i][j][0][0] = true;
 63                 }
 64             }
 65         }
 66 
 67         bool ok = false;
 68 
 69         while(que.empty() == false){
 70             QueNode u = que.front();
 71             que.pop();
 72             // while wukong reaches the room in which Monk tang is
 73             // and wukong has enough keys
 74             if(ma[u.x][u.y] == 'T' && u.k == k){
 75                 std::cout << u.t << std::endl;
 76                 ok = true;
 77                 break;
 78             }
 79             // if wukong enter the room with snake and has not killed the snake
 80             // it takes 1 minute to kill it 
 81             if(ma[u.x][u.y] <= 'a'+5 && ma[u.x][u.y] >= 'a'+1){
 82                 int num = 1<<(ma[u.x][u.y] -'a'-1);
 83                 
 84                 /* if( u.s & num == 0) */
 85                 // the statement above is wrong
 86                 // pay attention to operator precedence
 87                 if( (u.s&num) == 0){
 88                     u.s |= num;
 89                     ++ u.t;
 90                     que.push(u);
 91                     vis[u.x][u.y][u.k][u.s] = true;
 92                     continue;
 93                 }
 94             }
 95             
 96             for(int i = 0; i < 4; ++ i){
 97                 QueNode v(u);
 98                 ++ v.t;
 99                 v.x += dir[i][0];
100                 v.y += dir[i][1];
101 
102                 if(ma[v.x][v.y] != '#'){
103                     if(ma[v.x][v.y] - '0' == u.k + 1){
104                         v.k = u.k + 1;
105                     }
106                     if(vis[v.x][v.y][v.k][v.s] == false){
107                         vis[v.x][v.y][v.k][v.s] = true;
108                         que.push(v);
109                     }
110                 }
111             }
112 
113         }
114         if(ok == false){
115             puts("impossible");
116         }
117 
118     }
119 
120 }

 

posted on 2015-06-29 03:07  TakeoffYoung  阅读(182)  评论(0编辑  收藏  举报