[HIHO1328]逃离迷宫(bfs,位压)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HIHO1328]逃离迷宫(bfs,位压)相关的知识,希望对你有一定的参考价值。
题目链接:http://hihocoder.com/problemset/problem/1328
这个题bfs到时候不止要存当前的坐标,还要存当前有哪几把钥匙。因为5把钥匙,所以可以直接用位来存,这样也可以解决一个房间里有好几把钥匙的情况。
还有就是走的过程中,一个点重复走多少次的问题,我们用vis(x,y,k)来记录坐标(x,y)的时候拿着钥匙位压后为k的情况,并且初始化成0x7f7f7f,每次更新最短路,假如有重复走并且拥有钥匙情况相同的情况就可以剪掉了。
1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 13 ┓┏┓┏┓┃ 14 ┃┃┃┃┃┃ 15 ┻┻┻┻┻┻ 16 */ 17 #include <algorithm> 18 #include <iostream> 19 #include <iomanip> 20 #include <cstring> 21 #include <climits> 22 #include <complex> 23 #include <cassert> 24 #include <cstdio> 25 #include <bitset> 26 #include <vector> 27 #include <deque> 28 #include <queue> 29 #include <stack> 30 #include <ctime> 31 #include <set> 32 #include <map> 33 #include <cmath> 34 using namespace std; 35 #define fr first 36 #define sc second 37 #define cl clear 38 #define BUG puts("here!!!") 39 #define W(a) while(a--) 40 #define pb(a) push_back(a) 41 #define Rint(a) scanf("%d", &a) 42 #define Rll(a) scanf("%I64d", &a) 43 #define Rs(a) scanf("%s", a) 44 #define Cin(a) cin >> a 45 #define FRead() freopen("in", "r", stdin) 46 #define FWrite() freopen("out", "w", stdout) 47 #define Rep(i, len) for(int i = 0; i < (len); i++) 48 #define For(i, a, len) for(int i = (a); i < (len); i++) 49 #define Cls(a) memset((a), 0, sizeof(a)) 50 #define Clr(a, x) memset((a), (x), sizeof(a)) 51 #define Full(a) memset((a), 0x7f7f, sizeof(a)) 52 #define lrt rt << 1 53 #define rrt rt << 1 | 1 54 #define pi 3.14159265359 55 #define RT return 56 #define lowbit(x) x & (-x) 57 #define onenum(x) __builtin_popcount(x) 58 typedef long long LL; 59 typedef long double LD; 60 typedef unsigned long long ULL; 61 typedef pair<int, int> pii; 62 typedef pair<string, int> psi; 63 typedef pair<LL, LL> pll; 64 typedef map<string, int> msi; 65 typedef vector<int> vi; 66 typedef vector<LL> vl; 67 typedef vector<vl> vvl; 68 typedef vector<bool> vb; 69 70 typedef struct Node { 71 int x, y; 72 int s; 73 int k; 74 Node() {} 75 Node(int xx, int yy, int ss, int kk) : x(xx), y(yy), s(ss), k(kk) {} 76 }Node; 77 const int dx[5] = {1,-1,0,0}; 78 const int dy[5] = {0,0,1,-1}; 79 const int maxn = 110; 80 int n, m, k; 81 int sx, sy, ex, ey; 82 int vis[maxn][maxn][33]; 83 char G[maxn][maxn]; 84 char ks[maxn][maxn]; 85 int ret; 86 queue<Node> q; 87 88 bool ok(int x, int y) { 89 return x >= 0 && y >= 0 && x < n && y < m && G[x][y] != ‘#‘; 90 } 91 92 bool yes(int x, int y, int k) { 93 if(G[x][y] == ‘.‘) return 1; 94 return k & (1 << (G[x][y] - ‘A‘)); 95 } 96 97 void bfs() { 98 while(!q.empty()) q.pop(); 99 q.push(Node(sx, sy, 0, 0)); 100 vis[sx][sy][0] = 0; 101 while(!q.empty()) { 102 Node t = q.front(); q.pop(); 103 // printf("%d\\n", t.k); 104 if(t.x == ex && t.y == ey) { 105 ret = min(ret, t.s); 106 return; 107 } 108 Rep(i, 4) { 109 int x = t.x + dx[i]; 110 int y = t.y + dy[i]; 111 if(ok(x, y)) { 112 int ck = t.k | ks[x][y]; 113 if(vis[x][y][ck] > t.s + 1 && yes(x, y, ck)) { 114 vis[x][y][ck] = t.s + 1; 115 q.push(Node(x, y, t.s+1, ck)); 116 } 117 } 118 } 119 } 120 } 121 122 int main() { 123 // FRead(); 124 int x, y; 125 while(~scanf("%d%d%d%d%d%d%d",&n,&m,&k,&sx,&sy,&ex,&ey)) { 126 Clr(vis, 0x7f7f); Cls(G); Cls(ks); ret = 0x7f7f; 127 Rep(i, n) Rs(G[i]); 128 Rep(i, k) { 129 Rint(x); Rint(y); 130 ks[x][y] |= (1 << i); 131 } 132 bfs(); 133 if(ret != 0x7f7f) printf("%d\\n", ret); 134 else printf("-1\\n"); 135 } 136 RT 0; 137 }
这种判断重复的方法是不对的,因为会在一个出不去而不停兜圈子,拿不到钥匙并且会超时。
1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 13 ┓┏┓┏┓┃ 14 ┃┃┃┃┃┃ 15 ┻┻┻┻┻┻ 16 */ 17 #include <algorithm> 18 #include <iostream> 19 #include <iomanip> 20 #include <cstring> 21 #include <climits> 22 #include <complex> 23 #include <cassert> 24 #include <cstdio> 25 #include <bitset> 26 #include <vector> 27 #include <deque> 28 #include <queue> 29 #include <stack> 30 #include <ctime> 31 #include <set> 32 #include <map> 33 #include <cmath> 34 using namespace std; 35 #define fr first 36 #define sc second 37 #define cl clear 38 #define BUG puts("here!!!") 39 #define W(a) while(a--) 40 #define pb(a) push_back(a) 41 #define Rint(a) scanf("%d", &a) 42 #define Rll(a) scanf("%I64d", &a) 43 #define Rs(a) scanf("%s", a) 44 #define Cin(a) cin >> a 45 #define FRead() freopen("in", "r", stdin) 46 #define FWrite() freopen("out", "w", stdout) 47 #define Rep(i, len) for(int i = 0; i < (len); i++) 48 #define For(i, a, len) for(int i = (a); i < (len); i++) 49 #define Cls(a) memset((a), 0, sizeof(a)) 50 #define Clr(a, x) memset((a), (x), sizeof(a)) 51 #define Full(a) memset((a), 0x7f7f7f, sizeof(a)) 52 #define lrt rt << 1 53 #define rrt rt << 1 | 1 54 #define pi 3.14159265359 55 #define RT return 56 #define lowbit(x) x & (-x) 57 #define onenum(x) __builtin_popcount(x) 58 typedef long long LL; 59 typedef long double LD; 60 typedef unsigned long long ULL; 61 typedef pair<int, int> pii; 62 typedef pair<string, int> psi; 63 typedef pair<LL, LL> pll; 64 typedef map<string, int> msi; 65 typedef vector<int> vi; 66 typedef vector<LL> vl; 67 typedef vector<vl> vvl; 68 typedef vector<bool> vb; 69 70 typedef struct Node { 71 int x, y; 72 int s; 73 int k; 74 Node() {} 75 Node(int xx, int yy, int ss) : x(xx), y(yy), s(ss) { k = 0; } 76 Node(int xx, int yy, int ss, int kk) : x(xx), y(yy), s(ss), k(kk) {} 77 }Node; 78 const int dx[5] = {1,-1,0,0}; 79 const int dy[5] = {0,0,1,-1}; 80 const int maxn = 110; 81 int n, m, k; 82 int sx, sy, ex, ey; 83 char G[maxn][maxn]; 84 char ks[maxn][maxn]; 85 int ret; 86 queue<Node> q; 87 88 bool ok(int x, int y) { 89 return x >= 0 && y >= 0 && x < n && y < m && G[x][y] != ‘#‘; 90 } 91 92 void bfs() { 93 while(!q.empty()) q.pop(); 94 q.push(Node(sx, sy, 0, 0)); 95 int wtf = 0; 96 while(!q.empty()) { 97 if(wtf++ == 9000000) return; 98 Node t = q.front(); q.pop(); 99 // printf("%d\\n", t.k); 100 if(t.x == ex && t.y == ey) { 101 ret = min(ret, t.s); 102 return; 103 } 104 Rep(i, 4) { 105 int x = t.x + dx[i]; 106 int y = t.y + dy[i]; 107 if(ok(x, y)) { 108 int cur = t.k | ks[x][y]; 109 if(G[x][y] == ‘.‘ || (cur & (1 << (G[x][y] - ‘A‘)))) { 110 q.push(Node(x, y, t.s+1, cur)); 111 } 112 } 113 } 114 } 115 } 116 117 int main() { 118 // FRead(); 119 int x, y; 120 while(~scanf("%d%d%d%d%d%d%d",&n,&m,&k,&sx,&sy,&ex,&ey)) { 121 Cls(G); Cls(ks); ret = 0x7f7f7f; 122 Rep(i, n) Rs(G[i]); 123 Rep(i, k) { 124 Rint(x); Rint(y); 125 ks[x][y] |= (1 << i); 126 } 127 bfs(); 128 if(ret == 0x7f7f7f) printf("-1\\n"); 129 else printf("%d\\n", ret); 130 } 131 RT 0; 132 }
以上是关于[HIHO1328]逃离迷宫(bfs,位压)的主要内容,如果未能解决你的问题,请参考以下文章