zoukankan      html  css  js  c++  java
  • HDU_1254——推箱子,两次BFS

    这题做的一把鼻涕一把泪,果断考虑不周555

    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 <cstdio>
      2 #include <queue>
      3 using namespace std;
      4 const int dir[4][2] = {0,1,0,-1,1,0,-1,0};
      5 int m, n, map[7][7];
      6 
      7 struct node
      8 {
      9     int x, y, step;
     10     int man_x, man_y;
     11     
     12     bool check(void)
     13     {
     14         if(x>=0 && x<m && y>=0 && y<n)                    
     15         {
     16             if(map[x][y] != 1)                            
     17             {
     18                 return true;
     19             }
     20         }
     21         return false;
     22     }
     23 }start, man, temp, next, u, v;
     24 
     25 bool BFS_Man(void)
     26 {    
     27     start.x = temp.man_x;
     28     start.y = temp.man_y;
     29     
     30     int mark[7][7] = {0};
     31     mark[start.x][start.y] = 1;
     32     
     33     queue<node>que;
     34     que.push(start);
     35     
     36     while(!que.empty())
     37     {
     38         u = que.front();
     39         que.pop();
     40         if(u.x == man.x && u.y == man.y)
     41         {
     42             return true;
     43         }
     44         for(int i=0;i<4;i++)
     45         {
     46             v.x = u.x + dir[i][0];
     47             v.y = u.y + dir[i][1];
     48             if(v.check() && !mark[v.x][v.y] && (v.x != temp.x || v.y != temp.y))    //越界,撞墙,重复,撞箱子 
     49             {
     50                 mark[v.x][v.y] = 1;
     51                 que.push(v);
     52             }
     53         }
     54     }
     55     return false;
     56 }
     57 
     58 int BFS_Box(void)
     59 {
     60     int mark[7][7][4] = {0};            //判重的时候需要一个三维数组,箱子从不同方向过来,人的位置是不一样的,也就意味着状态不一样 
     61     
     62     queue<node>que;
     63     que.push(start);
     64     
     65     while(!que.empty())
     66     {
     67         temp = que.front();
     68         que.pop();
     69         
     70         if(map[temp.x][temp.y] == 3)    //找到返回步数 
     71         {
     72             return temp.step;
     73         }
     74         
     75         for(int i=0;i<4;i++)
     76         {
     77             next.x = temp.x + dir[i][0];
     78             next.y = temp.y + dir[i][1];
     79             next.step = temp.step + 1;
     80             if(next.check() && mark[next.x][next.y][i] == 0)    //判断越界,撞墙,重复 
     81             {
     82                 man.x = temp.x - dir[i][0];
     83                 man.y = temp.y - dir[i][1];                            //人移动的目标坐标 
     84                 if(man.check())                                            //判断目标坐标是否越界,撞墙 
     85                 {
     86                     if(BFS_Man())                                            //搜索判断人是否可以移动到目标点 
     87                     {
     88                         next.man_x = temp.x;
     89                         next.man_y = temp.y;                                //更新当前人坐标 
     90                         
     91                         mark[next.x][next.y][i] = 1;
     92                         que.push(next);
     93                     }
     94                 }
     95             }
     96         }
     97     }
     98     return -1;
     99 }
    100 
    101 int main()
    102 {
    103     int T;
    104     scanf("%d",&T);
    105     while(T--)
    106     {
    107         scanf("%d%d",&m,&n);
    108         for(int i=0;i<m;i++)
    109         {
    110             for(int j=0;j<n;j++)
    111             {
    112                 scanf("%d",&map[i][j]);
    113                 if(map[i][j] == 2)        //记录箱子起点 
    114                 {
    115                     start.x = i;
    116                     start.y = j;
    117                     start.step = 0;
    118                 }
    119                 else if(map[i][j] == 4)    //记录人起点 
    120                 {
    121                     start.man_x = i;
    122                     start.man_y = j;
    123                 }
    124             }
    125         }
    126         printf("%d
    ",BFS_Box());
    127     }
    128     return 0;
    129 }
     
    ——现在的努力是为了小时候吹过的牛B!!
  • 相关阅读:
    开发工程师的职场人生路
    10 ASP.NET Performance and Scalability Secrets(转载推荐)
    手机号码归属地查询接口大全
    参数的秘密“纠结”的压缩比
    爱情本来并不复杂,来来去去不过三个字
    假如苹果、微软、谷歌造汽车 他们的区别是什么
    tomcat修改jsessionid在cookie中的名称
    virtualBox 中 linux 系统 相关配置
    htpasswd用法
    linux 防火墙
  • 原文地址:https://www.cnblogs.com/pingge/p/3210447.html
Copyright © 2011-2022 走看看