zoukankan      html  css  js  c++  java
  • hdu.1254.推箱子(bfs + 优先队列)

    推箱子

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

    Problem Description
    推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.
    现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.
     
    Input
    输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
     
    Output
    对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
     
    Sample Input
    1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
     
    Sample Output
    4
     
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<queue>
     5 int T ;
     6 int n , m ;
     7 const int M = 10 ;
     8 int map[M][M] ;
     9 bool vis[M][M][M][M] ;
    10 int move[][2] = {{1,0} , {-1 , 0} , {0,1} , {0 , -1} } ;
    11 struct node
    12 {
    13     int x , y ;
    14     int a , b ;
    15     int time ;
    16     bool operator < (const node &rhs ) const
    17     {
    18         return time > rhs.time ;
    19     }
    20 };
    21 
    22 int bfs (int sx , int sy , int mx , int my , int ex , int ey)
    23 {
    24     //printf ("Last---> (%d,%d)
    " , ex , ey ) ;
    25     node ans , tmp ;
    26     std::priority_queue<node> q ;
    27     memset (vis , 0 , sizeof(vis)) ;
    28     while ( !q.empty ()) q.pop () ;
    29     q.push ( (node) {sx , sy , mx , my , 0}) ;
    30     vis[sx][sy][mx][my] = 1 ;
    31     if (mx == ex && my == ey) return 0 ;
    32     while ( !q.empty ()) {
    33         ans = q.top () ; q.pop () ;
    34        // printf ("S----(%d,%d) tui (%d,%d)
    " , ans.x , ans.y , ans.a , ans.b ) ;
    35         for (int i = 0 ; i < 4 ; i ++) {
    36             tmp = ans ;
    37             tmp.x += move[i][0] ; tmp.y += move[i][1] ;
    38             if (tmp.x < 0 || tmp.y < 0 || tmp.x == n || tmp.y == m) continue ;
    39             if (map[tmp.x][tmp.y] == 1 ) continue ;
    40             if (tmp.x == tmp.a && tmp.y == tmp.b ) {
    41                 int x = tmp.x + move[i][0] , y = tmp.y + move[i][1] ;
    42                 if (x < 0 || y < 0 || x == n || y == m) continue ;
    43                 if (map[x][y] == 1) continue ;
    44                 tmp.a = x , tmp.b = y ;
    45                 tmp.time ++ ;
    46             }
    47             if (vis[tmp.x][tmp.y][tmp.a][tmp.b]) continue ;
    48             vis[tmp.x][tmp.y][tmp.a][tmp.b] = 1 ;
    49             q.push (tmp ) ;
    50            // printf ("(%d,%d) tui (%d,%d)
    " , tmp.x , tmp.y , tmp.a , tmp.b ) ;
    51             if (tmp.a == ex && tmp.b == ey) return tmp.time ;
    52         }
    53     }
    54     return - 1 ;
    55 }
    56 
    57 int main ()
    58 {
    59     //freopen ("a.txt" , "r" , stdin ) ;
    60     scanf ("%d" , &T ) ;
    61     while (T --) {
    62         scanf ("%d%d" , &n , &m ) ;
    63         int k ;
    64         int sx , sy , ex , ey , mx , my ;
    65         for (int i = 0 ; i < n ; i ++) for (int j = 0 ; j < m ; j ++) scanf ("%d" , &map[i][j]) ;
    66         for (int i = 0 ; i < n ; i ++) {
    67             for (int j = 0 ; j < m ; j ++) {
    68                 if (map[i][j] == 4) sx = i , sy = j ;
    69                 else if (map[i][j] == 2) mx = i , my = j ;
    70                 else if (map[i][j] == 3) ex = i , ey = j ;
    71             }
    72         }
    73         if ( (k = bfs (sx , sy , mx , my , ex , ey )) == -1) puts ("-1") ;
    74         else printf ("%d
    " , k ) ;
    75     }
    76     return 0 ;
    77 }
    78 [ Copy to Clipboard ]    [ Save to File]
    View Code


     

  • 相关阅读:
    B
    给定二叉树先序、中序遍历序列,求后序遍历
    24点游戏dfs求解
    设计模式之单例模式
    生产者—消费者模式示例
    LeetCode(3):Longest Substring Without Repeating Characters
    LeetCode(5):Longest Palindromic Substring
    LeetCode(60):Permutation Sequence
    LeetCode(50):Pow(x,n)
    LeetCode(69):Sqrt(x)
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4494740.html
Copyright © 2011-2022 走看看