推箱子 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\n",bfs(sx,sy,manx,many)); 121 } 122 return 0; 123 }