HDU_1254——推箱子,两次BFS

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

Problem Description
推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.
现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.
HDU_1254——推箱子,两次BFS
 

 

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\n",BFS_Box());

127     }

128     return 0;

129 }

 

 

你可能感兴趣的:(HDU)