HDU 5094 --Maze【BFS && 状态压缩】
Maze
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 903 Accepted Submission(s): 316
Spock, the deputy captain of Starship Enterprise, fell into Klingon’s trick and was held as prisoner on their mother planet Qo’noS.
The captain of Enterprise, James T. Kirk, had to fly to Qo’noS to rescue his deputy. Fortunately, he stole a map of the maze where Spock was put in exactly.
The maze is a rectangle, which has n rows vertically and m columns horizontally, in another words, that it is divided into n*m locations. An ordered pair (Row No., Column No.) represents a location in the maze. Kirk moves from current location to next costs
1 second. And he is able to move to next location if and only if:
Next location is adjacent to current Kirk’s location on up or down or left or right(4 directions)
Open door is passable, but locked door is not.
Kirk cannot pass a wall
There are p types of doors which are locked by default. A key is only capable of opening the same type of doors. Kirk has to get the key before opening corresponding doors, which wastes little time.
Initial location of Kirk was (1, 1) while Spock was on location of (n, m). Your task is to help Kirk find Spock as soon as possible.
Each test case consists of several lines. Three integers are in the first line, which represent n, m and p respectively (1<= n, m <=50, 0<= p <=10).
Only one integer k is listed in the second line, means the sum number of gates and walls, (0<= k <=500).
There are 5 integers in the following k lines, represents xi1, yi1, xi2, yi2, gi; when gi >=1, represents there is a gate of type gi between location (xi1, yi1) and (xi2,
yi2); when gi = 0, represents there is a wall between location (xi1, yi1) and (xi2, yi2), ( | xi1 - xi2 | + | yi1 - yi2 |=1, 0<= gi <=p
)
Following line is an integer S, represent the total number of keys in maze. (0<= S <=50).
There are three integers in the following S lines, represents xi1, yi1 and qi respectively. That means the key type of qi locates on location (xi1, yi1), (1<= qi<=p).
If there is no possible plan, output -1.
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1
把 map 数组初始化为 -1 了 ,測试例子都过不了,调试了2个多小时才发现 ,真是越来越都比了。
还要注意:一个地方可能多多个不同类型的钥匙,坑啊
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define maxn 55
using namespace std; int vis[maxn][maxn][1 << 11];
int map[maxn][maxn][maxn][maxn];
int keynum[maxn][maxn][11];//记录这个地点有哪几种钥匙
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int n, m, p, s, k;//p代表有几种钥匙。 struct node{
int x, y ,step, key;
friend bool operator < (node a , node b)
{
return a.step > b.step;
}
}; int check(node a, node b)
{
if(b.x <= 0 || b.x > n || b.y <= 0 || b.y > m)
return 0;
if(map[a.x][a.y][b.x][b.y] == 0)
return 0;
return 1;
} int BFS(){
priority_queue<node>q;
node now, next;
now.x = 1;
now.y = 1;
now.step = 0;
now.key = 0;
for(int j = 1; j <= 10; ++j){// 起点有钥匙
if(keynum[now.x][now.y][j])
now.key = now.key | (1 << j);
}
q.push(now);
vis[now.x][now.y][now.key] = 1;
while(!q.empty()){
now = q.top();
q.pop();
if(now.x == n && now.y == m){
return now.step;
}
for(int i = 0; i < 4; ++i){
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
next.step = now.step + 1;
//printf("--%d\n", next.step);
next.key = now.key;
if(check(now, next)){//now 和 next 之间没有墙
if(map[now.x][now.y][next.x][next.y] > 0){ //now 和 next 中间有门
if(next.key & (1 << map[now.x][now.y][next.x][next.y])){//有这个门的钥匙。能通过这个门到达next
for(int j = 1; j <= 10; ++j){ //推断点next是不是有钥匙
if(keynum[next.x][next.y][j])
next.key = next.key | (1 << j);
}
if(!vis[next.x][next.y][next.key]){
vis[next.x][next.y][next.key] = 1;
q.push(next);
}
}
}
else {
for(int j = 1; j <= 10; ++j){//推断点next是不是有钥匙
if(keynum[next.x][next.y][j]){
next.key = next.key | (1 << j);
}
}
if(!vis[next.x][next.y][next.key]){
vis[next.x][next.y][next.key] = 1;
q.push(next);
}
}
}
}
}
return -1;
} int main (){
while(scanf("%d%d%d", &n, &m, &p) != EOF){
scanf("%d", &k);
memset(map, -1, sizeof(map));
memset(vis, 0, sizeof(vis));
memset(keynum, 0, sizeof(keynum));
while(k--){
int x1, y1, x2, y2, t;
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &t);
map[x1][y1][x2][y2] = t;
map[x2][y2][x1][y1] = t;
}
scanf("%d", &s);
while(s--){
int x, y, t;
scanf("%d%d%d", &x, &y, &t);
keynum[x][y][t] = 1;
}
printf("%d\n", BFS());
}
return 0;
}
HDU 5094 --Maze【BFS && 状态压缩】的更多相关文章
- hdu 5094 Maze bfs
传送门:上海邀请赛E 给定一个n×m的迷宫,给出相邻格子之间的墙或者门的信息,墙说明不可走,假设是门则须要有相应的钥匙才干通过,问是否可以从(1,1)到达(n,m) 一个带状态的bfs,再另记一个状态 ...
- hdu 5094 Maze (BFS+状压)
题意: n*m的迷宫.多多要从(1,1)到达(n,m).每移动一步消耗1秒.有P种钥匙. 有K个门或墙.给出K个信息:x1,y1,x2,y2,gi 含义是(x1,y1)与(x2,y2)之间有gi ...
- hdu 5094 Maze 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...
- hdu 4057 AC自己主动机+状态压缩dp
http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...
- HDU 5025 Saving Tang Monk 【状态压缩BFS】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Time Limit: 2000/1000 MS (Java/O ...
- [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)
Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- hdu 5067 Harry And Dig Machine (状态压缩dp)
题目链接 bc上的一道题,刚开始想用这个方法做的,因为刚刚做了一个类似的题,但是想到这只是bc的第二题, 以为用bfs水一下就过去了,结果MLE了,因为bfs的队列里的状态太多了,耗内存太厉害. 题意 ...
- HDU 1074 Doing Homework (dp+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...
- POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)
题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...
- hdu1429 胜利大逃亡(续) 【BFS】+【状态压缩】
题目链接:https://vjudge.net/contest/84620#problem/K 题目大意:一个人从起点走到终点,问他是否能够在规定的时间走到,在走向终点的路线上,可能会有一些障碍门,他 ...
随机推荐
- js处理富文本编辑器转义、去除转义、去除HTML标签
富文本编辑器生成的HTML标签,进行转义,然后写入数据库,防止脚本注入: function htmlEncode(value){ return $('<div/>').text(value ...
- [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1474 Solved: 521[Submit][Stat ...
- Codeforces 856B - Similar Words
856B - Similar Words 题意 如果一个字符串可以通过去掉首位字母得到另一个字符串,则称两个字符串相似. 给出一个字符串集合,求一个新的字符串集合,满足新集合里的字符串是原字符串集合中 ...
- 初识.NET Core
dotnet new console dotnet new web dotnet new webapi dotnet run dotnet build -r win-x64 dotnet publis ...
- 在MYSQL中插入当前时间,就象SQLSERVER的GETDATE()一样,以及对mysql中的时间日期操作。
在看sql教程的时候,我学的是mysql,但是教程上面的一点在mysql里面是不支持的,所以就找了其他的替代的办法 sql教程上面是这样的: 通过使用类似 GETDATE() 这样的函数,DEFAUL ...
- [AGC012F]Prefix Median
题目大意: 给定一个长度为$2n-1(n\le50)$的数组$a$,可以重排$a$中的元素,生成一个长度为$n$的数组$b$,其中$b_i$为$a_1\sim a_{2i-1}$的中位数.求对于给定的 ...
- 搭建SSH框架–搭建篇
工具: IDE:My Eclipse 2015 数据库:Orcale 创建Web项目 1.1 名称:PersonalWeb 1.2 勾选创建web.xml 1.3 Finsh 搭建Spring框架 2 ...
- Telnet技术白皮书
转:http://www.cnpaf.net/Class/Telnet/200705/19978.html Telnet的应用不仅方便了我们进行远程登录,也给hacker们提供了又一种入侵手段和后门, ...
- php新浪云链接mysql与storage
1.首先要有一个新浪云服务器 2.链接数据库获取数据 mysql CREATE TABLE Persons(FirstName varchar(255),LastName varchar(255)); ...
- django+celery+redis实现运行定时任务
0.目的 在开发项目中,经常有一些操作时间比较长(生产环境中超过了nginx的timeout时间),或者是间隔一段时间就要执行的任务. 在这种情况下,使用celery就是一个很好的选择. cele ...