推箱子 hdu1254

推箱子 1  http://acm.hdu.edu.cn/showproblem.php?pid=1254
推箱子 2  http://acm.hzau.edu.cn/problem.php?id=1010
推箱子 3  https://www.bnuoj.com/v3/problem_show.php?pid=33683



一系列搜索的题目

先讲讲第一题,

题目意思:

       推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.

现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.

 

Input
输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
 
Output
对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.

给一组样例:

 

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

           题目思路:

双广搜,主线按照箱子到终点来搜索,一边搜索一边判断这一步是否可以走?思路挺简单,写起来比较容易吧,给个代码参考,不对还望指出来啊!谢谢了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cctype>
  4 #include <cmath>
  5 #include <set>
  6 #include <map>
  7 #include <list>
  8 #include <queue>
  9 #include <deque>
 10 #include <stack>
 11 #include <string>
 12 #include <bitset>
 13 #include <vector>
 14 #include <iostream>
 15 #include <algorithm>
 16 #include <stdlib.h>
 17 
 18 using namespace std;
 19 typedef long long LL;
 20 const int INF=2e9+1e8;
 21 const double eps=0.0000001;
 22 const int MM=15;
 23 
 24 
 25 int maze[MM][MM];
 26 bool vis[MM][MM][MM*MM];
 27 int m,n,dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; // m 行      n 列;
 28 struct node
 29 {
 30     int x,y,step;
 31     int px,py;
 32 };
 33 struct point
 34 {
 35     int x,y;
 36 };
 37 bool is_out(int x,int y)
 38 {
 39     if(x>=1&&x<=m&&y>=1&&y<=n) return true;
 40     return false;
 41 }
 42 bool is_arrive(int sx,int sy,int ex,int ey,int xx,int yy)
 43 {
 44     queue<point>q;
 45     bool visit[MM][MM];
 46     memset(visit,0,sizeof(visit));
 47     visit[sx][sy]=1;
 48     point first,second;
 49     first.x=sx,first.y=sy;
 50     q.push(first);
 51     while(!q.empty())
 52     {
 53         first=q.front();
 54         q.pop();
 55         if(first.x==xx&&first.y==yy) continue;
 56         if(first.x==ex&&first.y==ey) return true;
 57         for(int i=0; i<4; i++)
 58         {
 59             int x=first.x+dir[i][0],y=first.y+dir[i][1];
 60             if(is_out(x,y)&&maze[x][y]!=1&&visit[x][y]==0) //
 61             {
 62                 visit[x][y]=1;
 63                 second.x=x,second.y=y;
 64                 q.push(second);
 65             }
 66         }
 67     }
 68     return false;
 69 }
 70 int bfs(int sx,int sy,int px,int py)//对箱子进行广搜
 71 {
 72     memset(vis,0,sizeof(vis));
 73     vis[sx][sy][MM*px+py]=1;
 74     queue<node>q;
 75     node first,second;
 76     first.px=px,first.py=py,first.step=0;
 77     first.x=sx,first.y=sy;
 78     q.push(first);
 79     while(!q.empty())
 80     {
 81         first=q.front();
 82         q.pop();
 83         int x=first.x,y=first.y;
 84         int px=first.px,py=first.py;
 85         if(maze[x][y]==3) return first.step;
 86         for(int i=0; i<4; i++)
 87         {
 88             x=first.x+dir[i][0],y=first.y+dir[i][1];
 89             px=first.x-dir[i][0],py=first.y-dir[i][1];
 90             if(is_out(px,py)&&is_out(x,y)&&maze[x][y]!=1&&maze[px][py]!=1)
 91             {
 92                 if(vis[x][y][MM*px+py]==0&&is_arrive(first.px , first.py , px , py , first.x , first.y))
 93                 {
 94                     vis[x][y][MM*px+py]=1;
 95                     second.px=first.x,second.py=first.y;
 96                     second.step=first.step+1;
 97                     second.x=x,second.y=y;
 98                     q.push(second);
 99                 }
100             }
101         }
102     }
103     return -1;
104 }
105 int main()
106 {
107     int ncase;
108     scanf("%d",&ncase);
109     while(ncase--)
110     {
111         int i,j,sx,sy,manx,many;
112         scanf("%d %d",&m,&n);
113         for(i=1; i<=m; i++)
114             for(j=1; j<=n; j++)
115             {
116                 scanf("%d",&maze[i][j]);
117                 if(maze[i][j]==2) sx=i,sy=j;// 箱子起始位置
118                 if(maze[i][j]==4) manx=i,many=j;// 人的气势位置
119             }
120         printf("%d
",bfs(sx,sy,manx,many));
121     }
122     return 0;
123 }


原文地址:https://www.cnblogs.com/coded-ream/p/7207979.html