您的位置:首页 > 其它

hdu 1254 推箱子

2012-12-20 03:01 337 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254

Problem Description

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

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



[align=left]Input[/align]

输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.

[align=left]Output[/align]

对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.

[align=left]Sample Input[/align]

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


[align=left]Sample Output[/align]
4

弄了两个晚上了,终于弄出来了,第一次做没有考虑到人的情况,而且推箱子中,人不会动.然后用搜索,出现莫名奇妙的错误啊...

思路:

用广搜寻找最小步数,但推箱子需要满足以下几个条件:

1.人能走到推箱子的那个位置

2.人不能穿过箱子.

3.箱子可以回到前一状态的位置,但不是同一方向回到的.

AC code:

#include<stdio.h>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define M 8
int Maze[M][M];
int visited2[M][M][4];
int visited1[M][M];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int row,col;
struct Point
{
int x,y;
};
struct State
{
Point Box,People;
int step;
};
bool check(Point p)
{
if(p.x<0||p.y<0||p.x>=row||p.y>=col||Maze[p.x][p.y]==1)
return false;
return true;
}
bool bfs(Point a,Point b,int x,int y)
{
memset(visited1,0,sizeof(visited1));
visited1[a.x][a.y]=1;     //人的位置
visited1[x][y]=1;    //箱子的位置
queue<Point> Q;
Q.push(a);
int k;
Point current,temp;
while(!Q.empty())
{
current=Q.front();
Q.pop();
if(current.x==b.x&¤t.y==b.y) return true;
for(k=0;k<4;++k)
{
temp.x=current.x+dx[k];
temp.y=current.y+dy[k];
if(check(temp)&&!visited1[temp.x][temp.y])
{
Q.push(temp);
visited1[temp.x][temp.y]=1;
}
}
}
return false;
}
int main()
{
int test,sum;
scanf("%d",&test);
while(test--)
{
sum=-1;
memset(visited2,0,sizeof(visited2));
scanf("%d%d",&row,&col);
int i,j;
Point st,p;
for(i=0;i<row;++i)
{
for(j=0;j<col;++j)
{
scanf("%d",&Maze[i][j]);
if(Maze[i][j]==2)
{
st.x=i;
st.y=j;
}
if(Maze[i][j]==4)
{
p.x=i;
p.y=j;
}
}
}
State first,current,temp;
first.Box.x=st.x;
first.Box.y=st.y;
first.People.x=p.x;
first.People.y=p.y;
first.step=0;
queue<State> q;
q.push(first);
Point a,b;
int x,y;
while(!q.empty())
{
current=q.front();
q.pop();
if(Maze[current.Box.x][current.Box.y]==3)
{ sum=current.step;break;}
for(i=0;i<4;++i)
{
temp.Box.x=current.Box.x+dx[i];
temp.Box.y=current.Box.y+dy[i];
temp.step=current.step+1;
a.x=current.People.x;   a.y=current.People.y;        //a是人的位置
b.x=current.Box.x-dx[i]; b.y=current.Box.y-dy[i];        //b是推箱子的位置
x=current.Box.x;
y=current.Box.y;
temp.People.x=b.x;
temp.People.y=b.y;
if(check(temp.Box)&&check(temp.People)&&!visited2[temp.Box.x][temp.Box.y][i]&&bfs(a,b,x,y))
{

q.push(temp);
visited2[temp.Box.x][temp.Box.y][i]=1;
}
}
}
printf("%d\n",sum);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: