HDU 1254 推箱子
2016-12-05 22:36
246 查看
题目链接:点击打开链接
题目大意:现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格。
(搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动。)
思路:很简单的状态搜索题,大概就是对箱子采用BFS的思想,然后判断人是否可以走到箱子的对面(DFS/BFS),由于数据大,可以用四重标记数组来标记(Hash[M][M][M][M])不过有许多细节需要注意。
(1)采用DFS/BFS判断人是否可以到达箱子的对面时,要明确人不能穿过箱子,即对箱子标记flag[p.Bx][p.By] = 1;而且这个判断是每次推动箱子之前都要判断的。
(2)求箱子的移动后的位置的坐标时要保证这个坐标没有超边界。
(3)DFS时不需要回溯。(设置标记数组,查找到即标记,不再查找,因为也不必要。)
(4)经测试,推箱子时,人的位置随箱子的移动而移动可以AC,人不移动(即人仍然在箱子上一步所在的位置)也可以AC。
代码如下:
题目大意:现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格。
(搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动。)
思路:很简单的状态搜索题,大概就是对箱子采用BFS的思想,然后判断人是否可以走到箱子的对面(DFS/BFS),由于数据大,可以用四重标记数组来标记(Hash[M][M][M][M])不过有许多细节需要注意。
(1)采用DFS/BFS判断人是否可以到达箱子的对面时,要明确人不能穿过箱子,即对箱子标记flag[p.Bx][p.By] = 1;而且这个判断是每次推动箱子之前都要判断的。
(2)求箱子的移动后的位置的坐标时要保证这个坐标没有超边界。
(3)DFS时不需要回溯。(设置标记数组,查找到即标记,不再查找,因为也不必要。)
(4)经测试,推箱子时,人的位置随箱子的移动而移动可以AC,人不移动(即人仍然在箱子上一步所在的位置)也可以AC。
代码如下:
#include<string> #include<string.h> #include<cstring> #include<stack> #include<queue> #include<algorithm> #include<math.h> #include<vector> #include<iomanip> #include<map> #include<iostream> using namespace std; const int M=8; const int dx[]={-1,1,0,0}; const int dy[]={0,0,-1,1}; int maze[M][M]; int n,m; int Nx,Ny; int Bx,By,Mx,My; int flag[M][M],Hash[M][M][M][M]; int Found; struct node { int Bx,By; int Mx,My; int step; }; int check(int x,int y) { //判断越界及墙壁 if(x>=0&&y>=0&&y<m&&x<n&&maze[x][y]!=1) return 1; return 0; } void dfs(int Nx 4000 ,int Ny,int Mx,int My) {//搜索人是否能到达挨着箱子并且与箱子运动相反方向的坐标上 if(Nx==Mx&&Ny==My) { Found=1; return; } for(int i=0;i<4&&!Found;i++) { int x=Nx+dx[i]; int y=Ny+dy[i]; if(check(x,y)&&!flag[x][y]) { flag[x][y]=1; dfs(x,y,Mx,My); } } } void bfs(int Bx,int By,int Mx,int My) { //搜索箱子 queue<node>Q; node p,q; p.Bx=Bx;p.By=By;p.Mx=Mx;p.My=My;p.step=0; Q.push(p); while(!Q.empty()) { p=Q.front();Q.pop(); if(maze[p.Bx][p.By]==3) { printf("%d\n",p.step); return; } for(int i=0;i<4;i++) { q=p; q.Bx+=dx[i]; q.By+=dy[i]; Nx=p.Bx-dx[i]; Ny=p.By-dy[i]; if(check(q.Bx,q.By)&&check(Nx,Ny)&&!Hash[q.Bx][q.By][Nx][Ny]) { memset(flag,0,sizeof(flag)); flag[p.Bx][p.By]=flag[Nx][Ny]=1; Found=0; dfs(Nx,Ny,p.Mx,p.My); if(Found) { Hash[q.Bx][q.By][Nx][Ny]=1; q.Mx=p.Bx;q.My=p.By; //这里也可以写成q.Mx=Nx;q.My=Ny; q.step++; Q.push(q); } } } } printf("-1\n"); return; } void init() { memset(Hash,0,sizeof(Hash)); memset(maze,0,sizeof(maze)); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%d",&maze[i][j]); if(maze[i][j]==2) { Bx=i; By=j; } if(maze[i][j]==4) { Mx=i; My=j; } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); bfs(Bx,By,Mx,My); } return 0; }
相关文章推荐
- hdu 1254 推箱子/poj 1475 Pushing Boxes(推箱子经典问题,BFS嵌套BFS)
- HDU 1254-推箱子
- hdu 1254 推箱子(嵌套搜索)
- 【BFS+DFS】hdu 1254 推箱子
- hdu 1254 推箱子 双层bfs
- HDU 1254 推箱子
- hdu 1254 推箱子(两次广搜)
- HDU 1254推箱子(bfs+dfs)
- hdu 1254 推箱子
- HDU 1254 推箱子
- hdu 1254 推箱子 BFS
- HDU 1254 推箱子(广搜+优先队列)
- hdu 1254 推箱子
- hdu 1254 推箱子
- hdu 1254-推箱子
- hdu 1254 推箱子
- HDU 1254推箱子
- HDU 1254 推箱子(双层BFS)
- hdu - 1254 推箱子 (bfs+bfs)
- HDU 1254 推箱子 (搜索中套搜索,BFS + DFS 这感觉,酸爽!)