hdu 1254 推箱子(双重bfs)
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
分析:
推箱子的游戏规则就不用多少了把,相信大家都玩过。我们主要的就是根据箱子现在的为止来考虑它下一步能够走到的为止,但是仅仅箱子能够走到这里来是不行的啊,箱子毕竟得有人推着才能往前走,也就意味着在箱子能走到这个位置时,还要判断人能不能够走到对应得位置,这一点是十分关键的。
用广搜寻找最小步数,但推箱子需要满足以下几个条件:
1.人能走到推箱子的那个位置
2.人不能穿过箱子.
3.箱子可以回到前一状态的位置,但不是同一方向回到的.
代码:
#include <cstdio>
#include <iostream>
#include <queue>
#include<string.h>
using namespace std;
const int maxn = 10;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
struct Node
{
int x,y,step;
Node(int x,int y,int step = -1): x(x), y(y), step(step) {}
};
int n,m,sx,sy,ex,ey,tmp[maxn][maxn];
int dist[maxn][maxn][4],px,py;
bool vis[maxn][maxn];
bool bfs1(int x1,int y1,int x2,int y2)
{
if(tmp[x1][y1] != 0 || tmp[x2][y2] != 0) return false;
queue<int> qx,qy;
qx.push(x1);
qy.push(y1);
memset(vis,0,sizeof(vis));
vis[x1][y1] = true;
while(!qx.empty())
{
int x = qx.front(), y = qy.front();
qx.pop();
qy.pop();
if(x == x2 && y == y2) return true;
for(int i = 0; i < 4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if(!vis[nx][ny] && tmp[nx][ny] == 0)
{
qx.push(nx);
qy.push(ny);
vis[nx][ny] = true;
}
}
}
return false;
}
int bfs()
{
queue<Node> box,man;
box.push(Node(sx,sy,0));
man.push(Node(px,py));
for(int i = 0; i < 4; i++) dist[sx][sy][i] = -1;
int x,y,nx,ny,xp,yp,nxp,nyp,pre;
while(!box.empty())
{
Node nowbox = box.front(), nowman = man.front();
box.pop();
man.pop();
x = nowbox.x;
y = nowbox.y;
pre = nowbox.step;
xp = nowman.x;
yp = nowman.y;
//printf("box: %d %d man: %d %d time: %d\n",x,y,xp,yp,dist[x][y][pre]);
if(x == ex && y == ey) return dist[x][y][pre] + 1;
for(int i = 0; i < 4; i++)
{
nx = x + dx[i];
ny = y + dy[i];
nxp = x - dx[i];
nyp = y - dy[i];
tmp[x][y] = 1;
if((dist[nx][ny][i] == -1 || dist[nx][ny][i] >= dist[x][y][pre] + 1)
&& tmp[nx][ny] == 0
&& bfs1(xp,yp,nxp,nyp))
{
dist[nx][ny][i] = dist[x][y][pre] + 1;
box.push(Node(nx,ny,i));
man.push(Node(x,y));
}
tmp[x][y] = 0;
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(dist,-1,sizeof(dist));
memset(tmp,0x3f,sizeof(tmp));
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%d",&tmp[i][j]);
if(tmp[i][j] == 2)//箱子起点
{
sx = i;
sy = j;
}
if(tmp[i][j] == 3)//箱子终点
{
ex = i;
ey = j;
}
if(tmp[i][j] == 4)//搬运工位置
{
px = i;
py = j;
}
if(tmp[i][j] != 1) tmp[i][j] = 0;
}
}
printf("%d\n",bfs());
}
return 0;
}
hdu 1254 推箱子(双重bfs)的更多相关文章
- HDU 1254 推箱子(BFS加优先队列)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others) Me ...
- HDU 1254 推箱子(BFS)
Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不 ...
- HDU 1254 推箱子 BFS
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目分析: 做这道题,感觉挺简单的,做着做着就错了20次, 我也是醉了, WA到吐的节奏啊! 思 ...
- hdu - 1254 推箱子 (bfs+bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...
- hdu.1254.推箱子(bfs + 优先队列)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu 1254 推箱子(搜索)
我写的第一道感觉比较难的搜索 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先要推箱子的话要满足人能够在箱子旁边,而且人的对面也是可通的. ...
- [HDU 1254] 推箱子
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 1254 推箱子游戏(搞了一下午。。。)
中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...
随机推荐
- MiniUI框架合并单元格
在项目中遇到合并单元格的问题,所以总结一下. 用的是miniUI框架,所以只谈miniUI中的单元格合并. (1)必须添加onLoad="onLoad" (2)需要在JS中进行单元 ...
- Ubuntu 14.04(64bit)使用mentohust连接校园网
ubuntu14.04系统安装成功之后,需要连接上网络才可以对更新系统以及安装一些必须包.而在学校中,经常遇到的情况需要通过锐捷客户端来连接校园网. 更新: 在Ubuntu14.04下面不用装ment ...
- javascript 进阶篇1 正则表达式,cookie管理,userData
首先,什么事正则表达式呢,其实引入概念很多时候并不能帮我们明白它到底是什么,所以我先简单描述下,正则表达式,其实就是一个记录字符串规则则的字符串,等我们看完这一部分,也就能明白它到底是什么了. 基本语 ...
- 【Java并发编程】之一:可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- nginx配置虚拟路径下载文件(.apk)
公司将安卓apk文件放到服务器上,实现用户点击链接并下载 nginx version 1.14.1 nginx配置修改 server { listen 80; server_name localhos ...
- 左连接,右连接和等值连接(left join,right join和inner join)
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...
- python selenium wait方法
遇到一个网站运行很慢,所以要等待某个元素显示出来之后再进行操作,自己手上的书上没有例子可以直接用 发现一篇文章:http://www.cnblogs.com/yoyoketang/p/6517477. ...
- WampServer3.0允许局域网访问配置教程
wamp server 下的Apache默认设置是不允许外网访问和局域网访问的,而直接搜索 wamp局域网访问配置,出现都是一些旧版本的wamp的配置信息,最新版本3.0.X需要使用以下配置方法: 配 ...
- MT【126】点对个数两题之二【图论】
在平面上有\(n\) 个点$S={x_1,x_2\cdots,x_n}, $ 证明在这 \(n\) 个点中距离为 \(1\) 的点对数不超过 \(\dfrac{n}{4}+\dfrac{2}{2}n^ ...
- Alpha 冲刺 —— 十分之五
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 协助测试的进行 测试项目运行的服务器环境 ...