题目链接: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. Spring Mvc 返回机制

    转自:http://jianzh5.iteye.com/blog/1909234 Spring Mvc 有如下的几种返回方式: ModelAndView, Model, ModelMap, Map, ...

  2. git shell 中文

    alias ls="ls --show-control-chars" alias ll="ls -l"

  3. iOS常见各种ID

    //CFUUID CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault); NSString *cfuuidString = (NSString*)C ...

  4. 动态修改 NodeJS 程序中的变量值

    如果一个 NodeJS 进程正在运行,有办法修改程序中的变量值么?答案是:通过 V8 的 Debugger 接口可以!本文将详细介绍实现步骤. 启动一个 HTTP Server 用简单的 Hello ...

  5. [Qt] 界面美化 [2013-06-17更新](转载)

    - 经验总结 1. 可用对话框(QDialog)模拟类似Android中toast的效果.     - 设置程序界面风格 在main函数中QApplication::setStyle("wi ...

  6. iOS获取手机相关信息

    iOS具体的设备型号: #include <sys/types.h> #include <sys/sysctl.h> - (void)test { //手机型号. size_t ...

  7. POJ 1185 炮兵阵地 (状压DP)

    题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...

  8. 机器学习之多变量线性回归(Linear Regression with multiple variables)

    1. Multiple features(多维特征) 在机器学习之单变量线性回归(Linear Regression with One Variable)我们提到过的线性回归中,我们只有一个单一特征量 ...

  9. lintcode:最大间隔

    题目 给定一个未经排序的数组,请找出其排序表中连续两个要素的最大间距. 如果数组中的要素少于 2 个,请返回 0. 注意事项 可以假定数组中的所有要素都是非负整数,且最大不超过 32 位整数. 样例 ...

  10. MySQL数据库的基本操作命令

    MySQL数据库的基本操作命令 [mysql]mysql 常用建表语句 一.mysql服务操作 net start mysql //启动mysql服务 net stop mysql //停止mysql ...