zoukankan      html  css  js  c++  java
  • 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
    ", solve());
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/4314194.html
Copyright © 2011-2022 走看看