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

思路;

1.由于求的是箱子的路径,则通过bfs去找箱子的最短路径

2.由于是人推箱子,所以在找箱子的路径是,需要通过bfs去判断人能否推箱子到那个路径上。

要点(嵌套bfs)

bfs_box时,需注意:是否在界内,是否不为墙,是否人能到推它的相应位置,判重(判断人是否已经在这里推过箱子了,防止TLE)

bfs_per时,需注意:是否在界内,是否不为墙,判重(人是否已经走过这)

 #include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int room[][];//房间布置
int n,m,res;//行、列 ,res为最终结果
struct node
{
int x,y,step;//x,y为坐标,step指箱子走过的路
}per,fin,box;//分别指人,终点,以及箱子
bool pvis[][];//人能到的位置
bool pbvis[][][][];//判重
int rx[]={,,,-};
int ry[]={,-,,};
void bfs_per()//找出人当前可以走的位置
{
queue<node>qper;
memset(pvis,false,sizeof(pvis));
qper.push(per);
node cur,next;
while(!qper.empty())
{
cur=qper.front();
qper.pop();
pvis[cur.x][cur.y]=true;
for(int i=;i<;i++)
{
next.x=cur.x+rx[i];
next.y=cur.y+ry[i];
if(next.x>=&&next.x<n&&next.y>=&&next.y<m)//在界内
if(room[next.x][next.y]==)//可走
if(!pvis[next.x][next.y])
qper.push(next);
}
}
}
void bfs_box()//找出箱子可移动的最短路径
{
queue<node>qbox;
qbox.push(box);
qbox.push(per);
node cur,next;
while(!qbox.empty())
{
cur=qbox.front();//box所在位置
qbox.pop();
per=qbox.front();//人的位置
qbox.pop();
if(cur.x==fin.x&&cur.y==fin.y)
{
if(res==-||cur.step<res)
res=cur.step;
return ;
}
pbvis[cur.x][cur.y][per.x][per.y]=true;
room[cur.x][cur.y]=;//箱子人是不能走的
bfs_per();//人可以到达的位置
room[cur.x][cur.y]=;//回溯
for(int i=;i<;i++)
{
next.x=cur.x+rx[i];
next.y=cur.y+ry[i];
next.step=cur.step+;
if(next.x>=&&next.x<n&&next.y>=&&next.y<m) //在界内
if(room[next.x][next.y]==)//箱子位置可达
if(pvis[cur.x-rx[i]][cur.y-ry[i]])//人能到箱子的反方向
if(!pbvis[next.x][next.y][cur.x][cur.y])//判重防止TLE
{
qbox.push(next);//箱子当前的位置
qbox.push(cur);// 人当前的位置
}
}
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=;i<n;i++)
for(int j=;j<m;j++)
{
cin>>room[i][j];
if(room[i][j]==)
box.x=i,box.y=j,box.step=;//初始化
else if(room[i][j]==)
fin.x=i,fin.y=j,room[i][j]=;//处理成可以走的地方
else if(room[i][j]==)
per.x=i,per.y=j,room[i][j]=;
}
res=-;
memset(pbvis,false,sizeof(pbvis));//都没有访问过
bfs_box();
printf("%d\n",res);
}
return ;
}

HDU 1254 推箱子(BFS)的更多相关文章

  1. HDU 1254 推箱子 BFS

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目分析: 做这道题,感觉挺简单的,做着做着就错了20次, 我也是醉了, WA到吐的节奏啊! 思 ...

  2. hdu - 1254 推箱子 (bfs+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...

  3. hdu.1254.推箱子(bfs + 优先队列)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  4. HDU 1254 推箱子(BFS加优先队列)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Me ...

  5. hdu 1254 推箱子(双重bfs)

    题目链接 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能 ...

  6. hdu 1254 推箱子(嵌套搜索,bfs中有dfs)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. hdu 1254 推箱子(搜索)

    我写的第一道感觉比较难的搜索 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先要推箱子的话要满足人能够在箱子旁边,而且人的对面也是可通的. ...

  8. [HDU 1254] 推箱子

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...

随机推荐

  1. 肿瘤基因组学数据库终结者:cBioPortal---转载

    转载自:http://blog.sciencenet.cn/blog-1509670-1000479.html 随着芯片和高通量测序技术的广泛应用,在肿瘤研究领域积累了越来越多的基因组学数据,特别是像 ...

  2. Ubuntu14.04 获取文件或者文件夹大小

    [root@bogon ~]# stat -c%s install.log

  3. Phpstorm配置scss不生成缓存

    --no-cache 加上这个,就不会生成 .sass-cache 文件夹了.

  4. Codeforces 680D - Bear and Tower of Cubes

    680D - Bear and Tower of Cubes 思路:dfs+贪心,设剩余的体积为res,存在a,使得a3 ≤ res,每次取边长为a的立方体或者边长为a-1的立方体(这时体积上限变成a ...

  5. Codeforces 352B - Jeff and Periods

    352B - Jeff and Periods 思路:水题,考验实现(implementation)能力,来一波vector[允悲]. 代码: #include<bits/stdc++.h> ...

  6. 生成全球唯一标识GUID

    有时候我们操作数据的时候需要给这些数据一些编码,而这些编码又希望永远不会重复!这个时候微软的C#给了我们一个函数,这个函数产生的编码全球唯一,永远不会重复! 方法如下: 1.C#生成方式 string ...

  7. 雷林鹏分享:C# 正则表达式

    C# 正则表达式 正则表达式 是一种匹配输入文本的模式..Net 框架提供了允许这种匹配的正则表达式引擎.模式由一个或多个字符.运算符和结构组成. 定义正则表达式 下面列出了用于定义正则表达式的各种类 ...

  8. javascript之构造函数的继承(引用网络)

    这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个" ...

  9. LeetCode--028--实现strSTR()

    问题描述: 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返回  -1. 示例 ...

  10. mysql--------大数据量分页sql语句优化

    分页程序原理很简单,这里就不多说了,本篇文章主要说的是在数据表记录量比较大的情况下,如何将分页SQL做到更优化,让MySQL执行的更快的方法. 一般的情况下,我们的分页SQL语句是这样的: ,; 以上 ...