zoukankan      html  css  js  c++  java
  • hdu 1072 有炸弹的迷宫 (DFS)

    题意:在n×m的地图上,0表示墙,1表示空地,2表示人,3表示目的地,4表示有定时炸弹重启器。定时炸弹的时间是6,人走一步所需要的时间是1。每次可以上、下、左、右移动一格。当人走到4时如果炸弹的时间不是0,可以重新设定炸弹的时间为6。如果人走到3而炸弹的时间不为0时,成功走出。求人从2走到3的最短时间。这个题中每个结点都是可以重复访问的,但其实,炸弹重置点不要重复走,因为,走到炸弹重置点时时间就会被设置为最大时间,当重新返回时时间又设成最大,但此时已走的步数肯定增加了


    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

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <queue>
     5 using namespace std;
     6 
     7 int n , m  ;
     8 int sx , sy  ;
     9 int  map[11][11] ;
    10 int step[11][11] ;
    11 int t[11][11] ;
    12 int MIN ;
    13 
    14 
    15 
    16 int dx[] = {1,-1,0,0} ;
    17 int dy[] = {0,0,1,-1} ;
    18 
    19 void dfs(int x ,int y , int len , int sum)
    20 {
    21     if (x<0 || y<0 || x>=n || y>=m || len <= 0 || sum >= MIN)
    22         return  ;
    23     if (map[x][y] == 0)
    24         return ;
    25     if (map[x][y] == 3)
    26     {
    27         if (sum < MIN)
    28             MIN = sum ;
    29         return ;
    30     }
    31     if (map[x][y] == 4)
    32         len = 6 ;
    33     if (sum >= step[x][y] && len <=t[x][y] ) //如果转了一圈 又转回来了 就要剪掉
    34         return ;
    35     step[x][y] = sum ; //当前步数
    36     t[x][y] = len ;    //剩余时间
    37     int fx , fy ;
    38     for(int i = 0 ; i < 4 ; i++)
    39     {
    40         fx = x + dx[i] ;
    41         fy = y + dy[i] ;
    42         dfs(fx,fy,len-1,sum+1) ;
    43     }
    44 
    45 }
    46 
    47 
    48 
    49 int main ()
    50 {
    51    // freopen("in.txt","r",stdin) ;
    52     int T ;
    53     scanf("%d" , &T) ;
    54     while (T--)
    55     {
    56          scanf("%d %d" , &n , &m) ;
    57          for (int i = 0 ; i < n ; i++)
    58             for (int j = 0 ; j < m ; j++)
    59          {
    60              cin>>map[i][j] ;
    61              step[i][j] = INT_MAX ;
    62              if (map[i][j] == 2)
    63              {
    64                  sx = i ;
    65                  sy = j ;
    66              }
    67 
    68 
    69          }
    70          memset(t , 0 ,sizeof(t)) ;
    71          MIN = INT_MAX ;
    72          int len = 6 ;
    73          int sum = 0 ;
    74          dfs(sx,sy,len,sum) ;
    75          if (MIN == INT_MAX)
    76             printf("-1
    ") ;
    77          else
    78             printf("%d
    " , MIN) ;
    79 
    80     }
    81 
    82     return 0 ;
    83 }
    View Code
  • 相关阅读:
    广度遍历有向图
    坚持的力量 第二十一篇
    坚持的力量 第二十二篇
    搜索引擎首页
    安装ubuntu
    最小生成树之Kruskal算法
    最小生成树之PRIM算法
    文件同步软件
    [恢]hdu 2151
    [恢]hdu 1396
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/4518477.html
Copyright © 2011-2022 走看看