[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 }

时间: 2024-10-17 16:46:38

[HIHO1328]逃离迷宫(bfs,位压)的相关文章

hdu 1728 逃离迷宫 bfs记转向

题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18702    Accepted Submission(s): 4526 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,g

hdu 1728 逃离迷宫 bfs记步数

题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18702    Accepted Submission(s): 4526 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,g

杭电 逃离迷宫 BFS

给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去.令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的.我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一

HDU 1728 逃离迷宫 BFS

其实就是让你找最少的拐弯次数,dk数组记录到一个点的最少拐弯次数,每次让一个方向上的所有点进队就好了. 注意如果拐弯次数相等还是可以进队的,因为过来的方向可能不一样. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #inclu

hdu1728逃离迷宫 bfs

//bfs用vis[i][x][y][k] 表示从i的方向到x,y且剩下的转弯数是k #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn = 110 ; int vis[4][maxn][maxn][maxn] ; char map[maxn][maxn] ; struct node { int k

hdu1728 逃离迷宫bfs

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1728/ 关于广度优先搜索的第一篇题解.广度优先搜索,就是状态树的层次遍历,一层一层的搜索,直到搜索到目标状态为止.在扩展的过程中设定一种由上一层扩展到下一层的转化机制,将出现的新的状态放入队列之中,每次取出队首元素,大部分情况下bfs是用来搜索最优值的问题,优先队列的作用就是一旦搜索到目标状态,跟随的结果状态一定是最优的.为了避免重复相同的搜索,可设置访问记录.一般运用队列这种数据结构,使得最初搜索的状态在前

逃离迷宫(HDU 1728 BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 21384    Accepted Submission(s): 5180 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方

hdu 1728 逃离迷宫 (BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14376    Accepted Submission(s): 3458 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方

HDU1728 逃离迷宫 【BFS】

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16840    Accepted Submission(s): 4108 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地