您的位置:首页 > 其它

HDU 1254 推箱子(广搜+优先队列)

2017-11-21 20:28 375 查看
Problem Description

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

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



 

Input

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

 

Output

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

 

Sample Input

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

 

Sample Output

4

 

Author

Ignatius.L & weigang Lee

#include <iostream>
#include <queue>
#include <memory.h>
using namespace std;
struct status
{
int bx,by;//箱子的坐标
int px,py;//人的坐标
int step;
bool friend operator <(const status& a,const status& b)//重载优先队列的比较符
{
return a.step>b.step;
}
};
int main()
{
int T,m,n;
int mmap[10][10];
int di[4][2]= {-1,0,1,0,0,-1,0,1};
bool visit_of_person[10][10][10][10];
priority_queue <status> q;
//使用优先队列可以使推动箱子次数多的状态推迟出队,从而保证箱子每个能推动的方向都被访问到并推动
   //若直接使用队列,则无法使每种情况都走到
cin>>T;
for(int Ti=0; Ti<T; ++Ti)
{
memset(visit_of_person,false,10000);
status start;
start.step=0;
int endx,endy;
int ans=0;
cin>>m>>n;
for(int i=0; i<m; ++i)
for(int j=0; j<n; ++j)
{
cin>>mmap[i][j];
if(mmap[i][j]==2)
start.bx=i,start.by=j;
else if(mmap[i][j]==3)
endx=i,endy=j;
else if(mmap[i][j]==4)
start.px=i,start.py=j;
}
q.push(start);
bool found=false;
while(!q.empty()&&!found)
{
for(int i=0; i<4; ++i)
{
status cur_status=q.top();
cur_status.px+=di[i][0];
cur_status.py+=di[i][1];
//先判越界,否则可能出现数组下标为负的情况
if(cur_status.px<0||cur_status.px>=m||cur_status.py<0||cur_status.py>=n)//越界
continue;
if(mmap[cur_status.px][cur_status.py]==1)//走到墙上
continue;
if(visit_of_person[cur_status.bx][cur_status.by][cur_status.px][cur_status.py])//该状态已经走过
continue;
if(cur_status.px==cur_status.bx&&cur_status.py==cur_status.by)//走到箱子上
{
int next_box_x=cur_status.bx+di[i][0];
int next_box_y=cur_status.by+di[i][1];
if(next_box_x<0||next_box_x>=m||next_box_y<0||next_box_y>=n)//箱子越界
continue;
if(mmap[next_box_x][next_box_y]==1)//箱子走到墙上
continue;
//箱子既没走到墙上也没越界,则箱子走一步
cur_status.bx=next_box_x;
cur_status.by=next_box_y;
++cur_status.step;
if(cur_status.bx==endx&&cur_status.by==endy)//箱子走到终点
{
found=true;
ans=cur_status.step;
}
}
q.push(cur_status);
visit_of_person[cur_status.bx][cur_status.by][cur_status.px][cur_status.py]=true;
}
q.pop();
}
if(found)
cout<<ans<<endl;
else
cout<<-1<<endl;
while(!q.empty())//清空队列
q.pop();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: