您的位置:首页 > 其它

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。

代码如下:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: