[HIHO1328]逃离迷宫(bfs,位压)
题目链接: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,位压)的更多相关文章
- hdu 1728 逃离迷宫 (BFS)
逃离迷宫 Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissi ...
- hdu 1728 逃离迷宫 bfs记转向
题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others) Mem ...
- hdu 1728 逃离迷宫 bfs记步数
题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others) Mem ...
- hdu_1728_逃离迷宫(bfs)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意:走迷宫,找最小的拐角 题解:对BFS有了新的理解,DFS+剪枝应该也能过,用BFS就要以拐 ...
- 杭电 逃离迷宫 BFS
给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位 ...
- HDU 1728 逃离迷宫 BFS题
题目描述:输入一个m*n的地图,地图上有两种点,一种是 . 表示这个点是空地,是可以走的,另一种是 * ,表示是墙,是不能走的,然后输入一个起点和一个终点,另外有一个k输入,现在要你确定能否在转k次弯 ...
- hdu 1728 逃离迷宫 BFS加优先队列 DFS()
http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意就是能否在规定的转弯次数内从起点走到终点.刚走时那步方向不算. 只会bfs(),但想到这题需要记录转弯 ...
- hdu1728 逃离迷宫bfs
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1728/ 关于广度优先搜索的第一篇题解.广度优先搜索,就是状态树的层次遍历,一层一层的搜索,直到搜索到目标状态为止 ...
- HDU 1728:逃离迷宫(BFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有 ...
随机推荐
- 委托、事件和Lambda
一.委托 delegate1.在.Net平台下,委托类型用来定义和响应应用程序中的回调.事实上,.Net委托类型是一个类型安全的对象,指向可以以后调用的其他方法,.Net委托是内置支持多路广播和异步方 ...
- Leetcode#117 Populating Next Right Pointers in Each Node II
原题地址 二叉树的层次遍历. 对于每一层,依次把各节点连起来即可. 代码: void connect(TreeLinkNode *root) { if (!root) return; queue< ...
- max_flow(Ford-Fulkerson) 分类: ACM TYPE 2014-09-02 01:50 110人阅读 评论(0) 收藏
#include <cstdio> #include <iostream> #include <cstring> #include<queue> usi ...
- 【bzoj1011】[HNOI2008]遥远的行星
1011: [HNOI2008]遥远的行星 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 3711 Solved ...
- Unity动态加载和内存管理(三合一)
原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Re ...
- poj 3710 Christmas Game 博弈论
思路:首先用Tarjan算法找出树中的环,环为奇数变为边,为偶数变为点. 之后用博弈论的知识:某点的SG值等于子节点+1后的异或和. 代码如下: #include<iostream> #i ...
- window内存管理与内存原理
转自: http://blog.csdn.net/iamfranter/article/details/6826270 WIndows为每个进程分配了4GB的虚拟地址空间,让每个进程都认为自己拥有4G ...
- volatile 关键字的复习
今天早上看何登成的微博(http://hedengcheng.com/?p=725) 对volatile 关键字语意进行了深入分析. 看完之后,用自己的话总结如下: 1.c/c++ volatile中 ...
- GetWindowText和GetDlgItemText的区别
二者使用方法相同,入口点不一样. 举例: CString str; /* if (GetDlgItem(IDC_Number1)->GetWindowText(str),str==" ...
- Junit单元测试学习笔记一
我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数 ...