Maze

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 903    Accepted Submission(s): 316

Problem Description
This story happened on the background of Star Trek.

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.

 

Input
The input contains many test cases.

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).

 

Output
Output the possible minimal second that Kirk could reach Spock.

If there is no possible plan, output -1.

 

Sample Input

4 4 9
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 &amp;&amp; 状态压缩】的更多相关文章

  1. hdu 5094 Maze bfs

    传送门:上海邀请赛E 给定一个n×m的迷宫,给出相邻格子之间的墙或者门的信息,墙说明不可走,假设是门则须要有相应的钥匙才干通过,问是否可以从(1,1)到达(n,m) 一个带状态的bfs,再另记一个状态 ...

  2. hdu 5094 Maze (BFS+状压)

    题意: n*m的迷宫.多多要从(1,1)到达(n,m).每移动一步消耗1秒.有P种钥匙. 有K个门或墙.给出K个信息:x1,y1,x2,y2,gi    含义是(x1,y1)与(x2,y2)之间有gi ...

  3. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  4. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  5. 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 ...

  6. [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  7. hdu 5067 Harry And Dig Machine (状态压缩dp)

    题目链接 bc上的一道题,刚开始想用这个方法做的,因为刚刚做了一个类似的题,但是想到这只是bc的第二题, 以为用bfs水一下就过去了,结果MLE了,因为bfs的队列里的状态太多了,耗内存太厉害. 题意 ...

  8. HDU 1074 Doing Homework (dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...

  9. POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)

    题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...

  10. hdu1429 胜利大逃亡(续) 【BFS】+【状态压缩】

    题目链接:https://vjudge.net/contest/84620#problem/K 题目大意:一个人从起点走到终点,问他是否能够在规定的时间走到,在走向终点的路线上,可能会有一些障碍门,他 ...

随机推荐

  1. js实现侧边栏信息展示效果

    目前的网页都右侧边栏,有的是在左侧,类似于导航栏,如一些购物商城,还有一些是在网页的右下角,一般是提示客服信息和微信/QQ等服务. 这里都涉及到一个动画效果的展示,即点击侧边栏时会在侧边栏的右侧或者左 ...

  2. 备份文件的python脚本(转)

    作用:将目录备份到其他路径.实际效果:假设给定目录"/media/data/programmer/project/python" ,备份路径"/home/diegoyun ...

  3. HDU 6322.Problem D. Euler Function -欧拉函数水题(假的数论题 ̄▽ ̄) (2018 Multi-University Training Contest 3 1004)

    6322.Problem D. Euler Function 题意就是找欧拉函数为合数的第n个数是什么. 欧拉函数从1到50打个表,发现规律,然后勇敢的水一下就过了. 官方题解: 代码: //1004 ...

  4. CF 990C. Bracket Sequences Concatenation Problem【栈/括号匹配】

    [链接]:CF [题意]: 给出n个字符串,保证只包含'('和')',求从中取2个字符串链接后形成正确的括号序列的方案数(每个串都可以重复使用)(像'()()'和'(())'这样的都是合法的,像')( ...

  5. dutacm.club Water Problem(矩阵快速幂)

    Water Problem Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Tot ...

  6. duboo服务使用thrift协议 + MQ

    写一篇博客来记录从 Python 转型到 Java 的学习成果.整体架构: rpc: dubbo + thrift idl: thrift registeration: zookeeper MQ: k ...

  7. [PKUSC2018]神仙的游戏(FFT)

    给定一个01?串,对所有len询问是否存在一种填法使存在长度为len的border. 首先有个套路的性质:对于一个长度为len的border,这个字符串一定有长度为n-len的循环节(最后可以不完整) ...

  8. 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行

    离线后以宗教为第一关键字,操作时间为第二关键字排序. <法一>块状树,线下ac,线上tle…… #include<cstdio> #include<cmath> # ...

  9. 焦点改变事件OnFocusChangeListener

    效果图 1.MainActivity.java package com.example.app2; import android.support.v7.app.AppCompatActivity; i ...

  10. spark 持久化机制

    spark的持久化机制做的相对隐晦一些,没有一个显示的调用入口. 首先通过rdd.persist(newLevel: StorageLevel)对此rdd的StorageLevel进行赋值,同chec ...