HDU 5025

选拔赛(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 }
时间: 2025-01-03 20:29:35

HDU 5025的相关文章

【线段树】 HDU 5025 A Corrupt Mayor&#39;s Performance Art

更新区间内颜色 输出区间内的颜色总数 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <math.h> using namespace std; #include <

HDU 5025 Saving Tang Monk(广州网络赛D题)

HDU 5025 Saving Tang Monk 题目链接 思路:记忆化广搜,vis[x][y][k][s]表示在x, y结点,有k把钥匙了,蛇剩余状态为s的步数,先把图预处理出来,然后进行广搜即可 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int N = 105; const int

hdu 5025 BFS + 优化 广东区域赛网赛

http://acm.hdu.edu.cn/showproblem.php?pid=5025 TLE了好几次 写的时候,问题在于, 1.钥匙怎么处理 参考了他人的写法,vis[key_num][i][j],相当于将图多维化,这样就可以判重了,否则只是按照普通的BFS,钥匙数不同的时候,可以重复,这个代码难易表达出来 另外此处一个很好的优化,当cost_now<cost[key_now][x_now][y_now]的时候,才q.push(Node)  这个剪枝很好啊 2.蛇怎么处理 没蛇的话,第一

HDU 5025 (BFS+记忆化状压搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5025 题目大意: 迷宫中孙悟空救唐僧,可以走回头路.必须收集完钥匙,且必须按顺序收集.迷宫中还有蛇,杀蛇多耗时1,蛇杀完就没了.问最少耗时. 解题思路: 2014广州网赛的水题之一.当时没刷过BFS状压,结果悲剧了. 首先这题可以压钥匙,也可以压蛇,不过压钥匙内存岌岌可危,于是就压蛇吧. 设f[x][y][key][snake]为在(x,y)点,已经取得的钥匙key,以及杀蛇snake的状态. 对

HDU 5025 Saving Tang Monk(BFS+状压)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5025 Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng'en during the Ming Dynasty. In this novel,

HDU 5025:Saving Tang Monk(BFS + 状压)

http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng'en during the Ming Dynasty. In

HDU 5025 Saving Tang Monk(状压搜索)

钥匙是必须有序,蛇是不要求有序的.所以一个需要状压一个不用 因为时间计算和步数计算不同.所以要遍历整个空间,或者使用优先队列.优先时间短的. 风格就这样了. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #define inf 0x3f3f3f3f #define maxn 110 using names

[ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 941    Accepted Submission(s): 352 Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Clas

ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng'en during the Ming Dynasty. In this novel, Monkey King Sun Wukong, pig Zhu Bajie and Sha Wujin

HDU 5025 状态压缩蛇+bfs+dp

题目大意:孙悟空要找到一条花费时间最短的路径,路上为S的代表有蛇,经过需多花一分钟,其他情况下都是走过花费一分钟,但数字必须依次得到,最后到了唐僧处,可以经过也可以救出,救出前提是得到所有种类的钥匙 这道题,我们不断找到到达每一个点的不同状态下的最小花费时间,用dp[N][N][11][status]来存,status代表所有蛇的状态,因为蛇只有5条,所以status<32,不会爆掉. 类似spfa中不断对某个状态进行弛缓操作,如果成功就更新数据后入队,否则不再入队. 这题之所以不能dfs来做,