HDU 1072 bfs

Nightmare

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7083    Accepted Submission(s): 3409

Problem Description

Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.

Given the layout of the labyrinth and Ignatius‘ start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.

Here are some rules:
1. We can assume the labyrinth is a 2 array.
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
3. If Ignatius get to the exit when the exploding time turns to 0, he can‘t get out of the labyrinth.
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can‘t use the equipment to reset the bomb.
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius‘ start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius‘ target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.

Output

For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.

Sample Input

3

3 3

2 1 1

1 1 0

1 1 3

4 8

2 1 1 0 1 1 1 0

1 0 4 1 1 0 4 1

1 0 0 0 0 0 0 1

1 1 1 4 1 1 1 3

5 8

1 2 1 1 1 1 1 4

1 0 0 0 1 0 0 1

1 4 1 0 1 1 0 1

1 0 0 0 0 3 0 1

1 1 4 1 1 1 1 1

Sample Output

4

-1

13

题目意思:

给出一个n*m的图,初始时一个人在map[i][j]=2处,只能向上、下、左、右移动1格,每走一步时间减1,初始化时间为6,当时间为1时还没找到出口3位置处,就输出1,否则输出最少走的步数,0是墙,1是空地,2是初始所在地方,3是目标,4可以把时间重置为6。

思路:

最优走迷宫问题一般就是bfs,模拟一下即可,判断下一步是否可走,若可走且走一步后时间不为0,就走这一步,然后判断此处是否是目标,是的话返回步数,是否是4,是的话更新时间。在我的代码中加了个visited[][]数组进行优化,因为每个位置最多走4次即可,再多的话进行无用功或者一直在两个地方之间徘徊跳不出bfs函数。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <queue>
 6 #include <iostream>
 7 using namespace std;
 8
 9 struct node {
10     int x, y, w, step;
11 };
12
13 int n, m;
14 int map[10][10];
15 int visited[10][10];
16 int xx[]={1,-1,0,0};
17 int yy[]={0,0,1,-1};
18
19 int judge(int x,int y){
20     if(map[x][y]==0||x<0||x>=n||y<0||y>=m) return 0;
21     return 1;
22 }
23
24 int bfs(int x,int y){
25     int i, j;
26     node p, q;
27     p.x=x;p.y=y;p.w=6;p.step=0;
28     queue<node>Q;
29     Q.push(p);
30     while(!Q.empty()){
31         p=Q.front();
32         Q.pop();
33         for(i=0;i<4;i++){
34             q.x=p.x+xx[i];
35             q.y=p.y+yy[i];
36             q.w=p.w-1;
37             q.step=p.step+1;
38             if(judge(q.x,q.y)){
39                 if(q.w>0&&visited[q.x][q.y]<4&&map[q.x][q.y]!=2){   //因为从2出发,再回到2已经多余了
40                     if(map[q.x][q.y]==3) return q.step;
41                     else if(map[q.x][q.y]==4){
42                         q.w=6;
43                     }
44                     visited[q.x][q.y]++;
45                     Q.push(q);
46                 }
47             }
48         }
49     }
50     return 0;
51 }
52 main()
53 {
54     int i, j, t, x, y;
55     cin>>t;
56     while(t--){
57         memset(visited,0,sizeof(visited));
58         scanf("%d %d",&n,&m);
59         for(i=0;i<n;i++){
60             for(j=0;j<m;j++){
61                 scanf("%d",&map[i][j]);
62                 if(map[i][j]==2){
63                     x=i;y=j;
64                 }
65             }
66         }
67         int ans=bfs(x,y);
68         if(!ans) printf("-1\n");
69         else printf("%d\n",ans);
70     }
71 }

HDU 1072 bfs,布布扣,bubuko.com

时间: 2024-11-07 03:14:15

HDU 1072 bfs的相关文章

hdu 1072(BFS) 有炸弹

http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目大意是在一个n×m的地图上,0表示墙,1表示空地,2表示人,3表示目的地,4表示有定时炸弹重启器. 定时炸弹的时间是6,人走一步所需要的时间是1.每次可以上.下.左.右移动一格. 当人走到4时如果炸弹的时间不是0,可以重新设定炸弹的时间为6.如果人走到3而炸弹的时间不为0时, 成功走出.求人从2走到3的最短时间. 一道典型的搜索,用的bfs,结构体中开一个step表示要求的时间,也就相当于步数,一个

HDU 1072 Nightmare (BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目大意: 走迷宫,初始剩余时间为6min,每步1min:到reset区是若剩余时间大于0,则可以重置.到终点3区,若时间大于0,则成功逃脱.(可以走回路) 0:wall 1:可以走 2:起点 3:终点 4:剩余时间重置为6 源代码: #include<iostream> #include<cstring> #include<cstdio> #include<q

HDU 1072 (不一样的入队条件) Nightmare

之前的BFS都是需要一个标记数组,但这个题不一样,因为可能一个格子不止走一次. 那么我们就要寻找新的入队条件:left比上次经过的时候大才入队(left表示上次经过该点时剩余的时间). 为什么呢?我们重复走过一个点只有一个可能,那就是为了去取那个,所以如果取完后再回头经过这个点的时候剩余时间变多了,我们的目的就达到了. left数组初值为0 优化: 重置时间的装置最多取一次就够了,所以可以再开一个标记数组vis记录装置是否用过. 1 //#define LOCAL 2 #include <cst

hdu 1175 bfs 转弯题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 和之前的1728类似.就是判断转弯数,建立一个用于记录转弯数的数组.. 还有就是对于特殊情况要进行考虑,比如起点与终点相同的情况,对于本题来说是不可以消去的应该输出NO.还有就是起点或终点是零这也是不行的,因为0代表没有棋子... 还有在判断能不能走的时候要小心,对于判断条件一定要小心,不要图赶快写.. 错误的地方都写在注释中了.. 代码: // hdu 1175 bfs 转弯数 //1.起点

Saving Princess claire_(hdu 4308 bfs模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=4308 Saving Princess claire_ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2305    Accepted Submission(s): 822 Problem Description Princess claire_ wa

hdu 1252 BFS

1 /* 2 题意:给出一个m*m矩阵表示的完全图,且每个点都有自环,每条边都有一种颜色:有三个玩家ABC的三张纸片分别初始在 3 某三个位置(可以重叠),纸片可以沿着边走一步,可以走的路径的规则为:若A要走到某个点i,则A-i的颜色要和B-C的颜 4 色相同:问最少要走多少步.(题意太难懂了,看了别人的说明才弄懂了题意) 5 6 题解:BFS 7 首先初步分析题意似乎很难用图论来解决,那么就是搜索/DP/数据结构,然后从搜索方面去思考的话,就是要找状态,然 8 后初步列出所有信息,三个点得位置

hdu 4707 bfs

bfs基础算法水题 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include<queue> using namespace std; const int Max = 1e5+50; int dist[Max]; vector<int> t

HDU 1072(记忆化BFS)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目大意:走迷宫.走到装置点重置时间,到达任一点时的时间不能为0,可以走重复路,求出迷宫最短时间. 解题思路: vis的第三维标记一下到这个格子的时间. 尽管可以格子可以重复走,但在相同时间到这个格子是没有意义的. 小心一下时间不能为0的问题就行了. #include "cstdio" #include "queue" #include "cstrin

hdu 1072 Nightmare BFS,第一次刷BFS的题,感好牛逼的。。。

Nightmare Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7758    Accepted Submission(s): 3723 Problem Description Ignatius had a nightmare last night. He found himself in a labyrinth with a ti