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 }
View Code

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值