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. quartz 配置运行

    这篇文章是对quartz 2.2.1进行配置 分为spring 整合版本和QuartzInitializerServlet整合版本 首先是QuartzInitializerServlet整合版本 主要 ...

  2. android studio 设置

    1.设置启动不打开最近项目 2.设置字体 3.安装逍游模拟器,并与android studio 进行链接 adb connect 127.0.0.1:21503 4.添加第三方包 文件jar.Modu ...

  3. 只用120行Java代码写一个自己的区块链-4实现真正的p2p网络

    在之前的文章中,我们模拟了节点网络通讯,很多朋友反馈说,他们想看真正的节点网络通讯而不是单节点的模拟.本章将满足你们.

  4. (3)三剑客之sed

    (1)基本介绍 1) 工作流程:sed每次处理一行内容,处理时,把当前处理的行存储在临时缓存区,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,直到内容处理完毕2 ...

  5. 安装tomcat7.0.82

    下载安装tomcat mkdir /tools cd /tools wget http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.82/bin/ap ...

  6. UVA 11636.Hello World!-水题

    Hello World! Time limit: 1.000 seconds When you first made the computer to print the sentence “Hello ...

  7. CF 990A. Commentary Boxes【数学/模拟】

    [链接]:CF [题意]:对于一个数n,每次加一的代价是a,每次减一的代价是b,求被m整除时的最小代价. [分析]:分情况讨论,自己多举几个栗子. [代码]: #include<cstdio&g ...

  8. 福州三中集训day1

    第一天感觉很是不友好,好在我是学过搜索之后才听的课,不然估计得死在教室…. 某zld犇犇讲的很是强?今天主要是讲枚举和DFS,几道经典题目讲完,还没到下课时间, 然后讲起了float. 有空整理一下吧 ...

  9. linux历史命令

    "忘记历史的Linux用户注定要输入很多信息.” 这也让强有力的历史命令(包括Bash shell的历史变体)不仅在援引之前执行命令而不需重新输入它们时有用,在调用其它很少用到的命令时也有用 ...

  10. codeforces 314E Sereja and Squares

    discription Sereja painted n points on the plane, point number i (1 ≤ i ≤ n) has coordinates (i, 0). ...