题目链接:http://hihocoder.com/problemset/problem/1328

这个题bfs到时候不止要存当前的坐标,还要存当前有哪几把钥匙。因为5把钥匙,所以可以直接用位来存,这样也可以解决一个房间里有好几把钥匙的情况。

还有就是走的过程中,一个点重复走多少次的问题,我们用vis(x,y,k)来记录坐标(x,y)的时候拿着钥匙位压后为k的情况,并且初始化成0x7f7f7f,每次更新最短路,假如有重复走并且拥有钥匙情况相同的情况就可以剪掉了。

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%I64d", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lrt rt << 1
#define rrt rt << 1 | 1
#define pi 3.14159265359
#define RT return
#define lowbit(x) x & (-x)
#define onenum(x) __builtin_popcount(x)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef pair<LL, LL> pll;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; typedef struct Node {
int x, y;
int s;
int k;
Node() {}
Node(int xx, int yy, int ss, int kk) : x(xx), y(yy), s(ss), k(kk) {}
}Node;
const int dx[] = {,-,,};
const int dy[] = {,,,-};
const int maxn = ;
int n, m, k;
int sx, sy, ex, ey;
int vis[maxn][maxn][];
char G[maxn][maxn];
char ks[maxn][maxn];
int ret;
queue<Node> q; bool ok(int x, int y) {
return x >= && y >= && x < n && y < m && G[x][y] != '#';
} bool yes(int x, int y, int k) {
if(G[x][y] == '.') return ;
return k & ( << (G[x][y] - 'A'));
} void bfs() {
while(!q.empty()) q.pop();
q.push(Node(sx, sy, , ));
vis[sx][sy][] = ;
while(!q.empty()) {
Node t = q.front(); q.pop();
// printf("%d\n", t.k);
if(t.x == ex && t.y == ey) {
ret = min(ret, t.s);
return;
}
Rep(i, ) {
int x = t.x + dx[i];
int y = t.y + dy[i];
if(ok(x, y)) {
int ck = t.k | ks[x][y];
if(vis[x][y][ck] > t.s + && yes(x, y, ck)) {
vis[x][y][ck] = t.s + ;
q.push(Node(x, y, t.s+, ck));
}
}
}
}
} int main() {
// FRead();
int x, y;
while(~scanf("%d%d%d%d%d%d%d",&n,&m,&k,&sx,&sy,&ex,&ey)) {
Clr(vis, 0x7f7f); Cls(G); Cls(ks); ret = 0x7f7f;
Rep(i, n) Rs(G[i]);
Rep(i, k) {
Rint(x); Rint(y);
ks[x][y] |= ( << i);
}
bfs();
if(ret != 0x7f7f) printf("%d\n", ret);
else printf("-1\n");
}
RT ;
}

这种判断重复的方法是不对的,因为会在一个出不去而不停兜圈子,拿不到钥匙并且会超时。

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%I64d", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f7f, sizeof(a))
#define lrt rt << 1
#define rrt rt << 1 | 1
#define pi 3.14159265359
#define RT return
#define lowbit(x) x & (-x)
#define onenum(x) __builtin_popcount(x)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef pair<LL, LL> pll;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; typedef struct Node {
int x, y;
int s;
int k;
Node() {}
Node(int xx, int yy, int ss) : x(xx), y(yy), s(ss) { k = ; }
Node(int xx, int yy, int ss, int kk) : x(xx), y(yy), s(ss), k(kk) {}
}Node;
const int dx[] = {,-,,};
const int dy[] = {,,,-};
const int maxn = ;
int n, m, k;
int sx, sy, ex, ey;
char G[maxn][maxn];
char ks[maxn][maxn];
int ret;
queue<Node> q; bool ok(int x, int y) {
return x >= && y >= && x < n && y < m && G[x][y] != '#';
} void bfs() {
while(!q.empty()) q.pop();
q.push(Node(sx, sy, , ));
int wtf = ;
while(!q.empty()) {
if(wtf++ == ) return;
Node t = q.front(); q.pop();
// printf("%d\n", t.k);
if(t.x == ex && t.y == ey) {
ret = min(ret, t.s);
return;
}
Rep(i, ) {
int x = t.x + dx[i];
int y = t.y + dy[i];
if(ok(x, y)) {
int cur = t.k | ks[x][y];
if(G[x][y] == '.' || (cur & ( << (G[x][y] - 'A')))) {
q.push(Node(x, y, t.s+, cur));
}
}
}
}
} int main() {
// FRead();
int x, y;
while(~scanf("%d%d%d%d%d%d%d",&n,&m,&k,&sx,&sy,&ex,&ey)) {
Cls(G); Cls(ks); ret = 0x7f7f7f;
Rep(i, n) Rs(G[i]);
Rep(i, k) {
Rint(x); Rint(y);
ks[x][y] |= ( << i);
}
bfs();
if(ret == 0x7f7f7f) printf("-1\n");
else printf("%d\n", ret);
}
RT ;
}

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

  1. hdu 1728 逃离迷宫 (BFS)

    逃离迷宫 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissi ...

  2. hdu 1728 逃离迷宫 bfs记转向

    题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Mem ...

  3. hdu 1728 逃离迷宫 bfs记步数

    题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Mem ...

  4. hdu_1728_逃离迷宫(bfs)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意:走迷宫,找最小的拐角 题解:对BFS有了新的理解,DFS+剪枝应该也能过,用BFS就要以拐 ...

  5. 杭电 逃离迷宫 BFS

    给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位 ...

  6. HDU 1728 逃离迷宫 BFS题

    题目描述:输入一个m*n的地图,地图上有两种点,一种是 . 表示这个点是空地,是可以走的,另一种是 * ,表示是墙,是不能走的,然后输入一个起点和一个终点,另外有一个k输入,现在要你确定能否在转k次弯 ...

  7. hdu 1728 逃离迷宫 BFS加优先队列 DFS()

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意就是能否在规定的转弯次数内从起点走到终点.刚走时那步方向不算. 只会bfs(),但想到这题需要记录转弯 ...

  8. hdu1728 逃离迷宫bfs

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1728/ 关于广度优先搜索的第一篇题解.广度优先搜索,就是状态树的层次遍历,一层一层的搜索,直到搜索到目标状态为止 ...

  9. HDU 1728:逃离迷宫(BFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Problem Description   给定一个m × n (m行, n列)的迷宫,迷宫中有 ...

随机推荐

  1. 【BZOJ】【1406】【AHOI2007】密码箱

    数论 Orz iwtwiioi 果然数论很捉鸡>_>完全不知道怎么下手 $$x^2 \equiv 1 \pmod n \rightarrow (x+1)*(x-1)=k*n $$ 所以,我 ...

  2. 【BZOJ】【4010】【HNOI2015】菜肴制作

    拓扑排序 这题是要求N个点的一个拓扑序,且满足以下条件:编号1的位置尽可能靠前,在此基础上编号2的位置尽可能靠前…… 我看到这题的第一感觉:将拓扑排序用的队列改为优先队列,编号越小越早出来. 但是连样 ...

  3. 【BZOJ】【1717】【USACO 2006 Dec】Milk Patterns产奶的模式

    后缀数组 o(︶︿︶)o 唉傻逼了一下,忘了把后缀数组的字典范围改回20001,直接21交了上去,白白RE了两发……sigh 既然要找出现了K次的子串嘛,那当然要用后缀数组了>_>(因为我 ...

  4. Springmvc jar包介绍

    spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...

  5. HTML5 canvas 绘图步骤

    1.先把canvas选出来,不选出来你往哪儿画! var oCan=  document.getElementById('xxx'); 2.声明基于 canvas 的context对象,没他你怎么调用 ...

  6. NodeJS模块、包、NPM

    1.NodeJS模块        每一个Nodejs都是一个NodeJS模块,包括JS文件,JSON文本文件,二进制模块文件. a.模块的应用               新建一个文件mytest. ...

  7. HDU3507 Print Article(斜率优化dp)

    前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...

  8. 借助flexpaper实现word在线预览和打印

    为了实现word能够在web上尽量以原始的排版样式展现出来,选择基于activex控件的方式太过于依赖某种浏览器,并且存在可能需要花费金钱购买相应的控件产品:于是借助flexpaper这种flash展 ...

  9. 来认识下less css

    简介 感觉自己都out了,跟不上web时代的潮流了,前不久才刚接触这玩意,发觉lesscss在某些方面还挺有用的,说白了这东西就是一种动态的样式语言,语法类似于css,可以像java那样进行编译,生成 ...

  10. JDK环境变量解析

    设置环境变量 在java 中需要设置三个环境变量(1.5之后不用再设置classpath了,但个人强烈建议继续设置以保证向下兼用问题)JDK安装完成之后我们来设置环境变量:右击“我的电脑”,选择“属性 ...