hdu1072【bfs可重复走】

大意:

给一个矩阵   有一个六秒之内会爆炸的炸弹  爆炸事件在数值为4的位置会重置为6

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.

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

问从起点到达终点最少需要的步数

思路:

这个题为bfs  但是有一点比较不好想的就是 可以重复走一些点

所以不能只是单纯的标记而已

我们这样想   由于bfs是按层往外搜索的

对于每一个点  我们如果第二次都到的爆炸时间更长的话  我们就把这个点在此如队列  抽象的把它进行拆点

这样  既能保证步数最小  又能保证重复的时候不会少考虑

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6
 7 const int maxn = 10;
 8 int n, m;
 9 int a[maxn][maxn];
10 struct Node {
11     int x, y;
12     int le, ti;
13     Node() {
14         x = 0, y = 0, le = 0, ti = 0;
15     }
16 };
17
18 queue<Node> q;
19 int xx[4] = { 0, 0, 1, -1 };
20 int yy[4] = { 1, -1, 0, 0 };
21 int vis[maxn][maxn], tim[maxn][maxn];
22
23 int solve() {
24     while(!q.empty()) {
25         Node n1 = q.front(); q.pop();
26         if(a[n1.x][n1.y] == 3) {
27             return n1.ti;
28         }
29         if(n1.le == 1) continue;
30         for(int i = 0; i < 4; i++) {
31             int tx = n1.x + xx[i];
32             int ty = n1.y + yy[i];
33             int hah = n1.le - 1;
34             if(a[tx][ty] == 4) hah = 6;
35             if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] != 0) {
36                 if(!vis[tx][ty] || tim[tx][ty] < hah) {
37                     vis[tx][ty] = 1; tim[tx][ty] = hah;
38                     Node n2;
39                     n2.x = tx; n2.y = ty;
40                     n2.le = hah; n2.ti = n1.ti + 1;
41                     q.push(n2);
42                 }
43             }
44         }
45     }
46     return -1;
47 }
48
49 int main() {
50     int t;
51     scanf("%d",&t);
52     while(t--) {
53         while(!q.empty()) q.pop();
54         memset(vis, 0, sizeof(vis));
55         memset(tim, 0, sizeof(tim));
56         Node n0;
57         scanf("%d %d",&n, &m);
58         for(int i = 1; i <= n; i++) {
59             for(int j = 1; j <= m; j++) {
60                 scanf("%d",&a[i][j]);
61                 if(a[i][j] == 2) {
62                     vis[i][j] = 1;
63                     tim[i][j] = 6;
64                     n0.x = i;
65                     n0.y = j;
66                     n0.le = 6;
67                     n0.ti = 0;
68                 }
69             }
70         }
71         q.push(n0);
72         printf("%d\n", solve());
73     }
74     return 0;
75 }

时间: 2024-11-16 13:46:00

hdu1072【bfs可重复走】的相关文章

POJ 2594--Treasure Exploration【二分图 &amp;&amp; 最小路径覆盖 &amp;&amp; 点可以重复走 &amp;&amp; 传递闭包】

Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7343   Accepted: 3002 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored

走迷宫(用队列bfs并输出走的路径)

#include <iostream> #include <stack> #include <string.h> #include <stdio.h> #include<queue> #include<algorithm> using namespace std; int a[11][11]= { {1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1},{1

HDU1372,BFS象棋马走日

简单的对于bfs的运用,但是还是写的太慢了写了TMD的1H,主要是不熟悉,以后慢慢熟悉就好了,模型基本已经能建立了,主要出现bug是在方向数组的运用上面,一定要记得是从0开始的,而不是从1开始的,导致错误. #include<cstdio> #include<cstdlib> #include<iostream> using namespace std; /*bfs*/ //方向数组 int nextx[8][2]={ {-1,-2}, {-2,-1}, {1,2},

hdu1072 bfs时间优化剪枝

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

hdu1072(dfs和bfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 题意:有一个n*m的矩阵迷宫,2是起点,3是终点,0是墙不能走,1是路,现在有6分钟炸弹要爆炸,没走一步花一分钟,问你是否能到达终点 能,则输出最短时间,不能输出-1.而4是重置时间,将时间变为6分钟,注意的是,不能正好时间为0,到达终点或者重置时间. bfs的思路比较简单,就是从起点开始搜索.遇到终点则就是最短时间,遇到4(重置设备)时间变为6分钟,并将此地方变为墙,因为每个重置设备在保证时

[HIHO1328]逃离迷宫(bfs,位压)

题目链接:http://hihocoder.com/problemset/problem/1328 这个题bfs到时候不止要存当前的坐标,还要存当前有哪几把钥匙.因为5把钥匙,所以可以直接用位来存,这样也可以解决一个房间里有好几把钥匙的情况. 还有就是走的过程中,一个点重复走多少次的问题,我们用vis(x,y,k)来记录坐标(x,y)的时候拿着钥匙位压后为k的情况,并且初始化成0x7f7f7f,每次更新最短路,假如有重复走并且拥有钥匙情况相同的情况就可以剪掉了. 1 /* 2 ━━━━━┒ギリギ

HDU 1072(记忆化BFS)

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

HDU1728 逃离迷宫 【BFS】

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16840    Accepted Submission(s): 4108 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地

【算法】BFS+哈希解决八数码问题

15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖"X"; 拼图的目的是安排瓷砖以便它们排序为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15× 这里唯一合法经营是交流'X'与它共享一个边缘的瓷砖之一.作为一个例子,举动下列顺序解决了一个稍微加扰难题: 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6