题目链接: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. NYOJ-655 光棍的YY AC 分类: NYOJ 2013-12-29 19:24 224人阅读 评论(0) 收藏

    #include<stdio.h> #include<string.h> char str[210]; int max[210][52]={0}; int sum(int n, ...

  2. poj 3254

    状态压缩 dp dp[i][j] 为第 i 行状态为 j 的总数 #include <cstdio> #include <cstdlib> #include <cmath ...

  3. Sqli-labs less 64

    Less-64 此处的sql语句为 $sql="SELECT * FROM security.users WHERE id=(($id)) LIMIT 0,1"; 示例payloa ...

  4. 鼠标滚轮事件MouseWheel

    其实在大多数浏览器(IE6, IE7, IE8, Opera 10+, Safari 5+,Chrome)中,都提供了 "mousewheel" 事件.但杯具的是 Firefox ...

  5. POJ 2531 Network Saboteur (枚举+剪枝)

    题意:给你一个图,图中点之间会有边权,现在问题是把图分成两部分,使得两部分之间边权之和最大. 目前我所知道的有四种做法: 方法一:状态压缩 #include <iostream> #inc ...

  6. iOS视频压缩

    // // ViewController.m // iOS视频测试 // // Created by apple on 15/8/19. // Copyright (c) 2015年 tqh. All ...

  7. Android屏幕适应详解(一)

    一.关于布局适配 1.不要使用绝对布局 2.尽量使用match_parent 而不是fill_parent . 3.能够使用权重的地方尽量使用权重(android:layout_weight) 4.如 ...

  8. iOS多线程的初步研究(六)-- NSOperation

    iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...

  9. sshpass

    示例: ./sshpass -p ‘123456’  ssh -o StrictHostKeyChecking=no    root@192.168.1.15 ./sshpass -p ‘123456 ...

  10. Shell脚本基础I

    1.Linux shell类型 /bin/sh--已经被/bin/bash所取代 /bin/bash--就是Linux预设的shell /bin/ksh--由AT&T Bell lab发展出来 ...