HDU1254--推箱子(BFS+DFS)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 129 Accepted Submission(s): 59
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
Recommend
Ignatius.L
思路:
如果没有人,这看箱子的话,这是一个简单的BFS
但是,这道题目另一个限制因素:人。有的箱子位置是人推不到的
棕色为箱子,黑色为墙,蓝色为人,这种情况下箱子就不能往上去
所以我们在BFS箱子位置的同时,也要搜索人的位置(能否到达箱子的相反位置),这里我用的DFS写的
有一个需要注意的点:
箱子可以走回头路
例如如下样例:
5 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 2 1 1
4 0 3 0 0
若直接去掉标记数组当然可以解决,但这样的话铁定超时
另一个方法是使用一个三维的标记数组,分别记录箱子的位置与人的位置
代码如下:
#include<bits/stdc++.h>
using namespace std;
int m[10][10];
bool vis[10][10][4];
bool vi[10][10];
int M,N;
int endx,endy;
int dfsx,dfsy;
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct node
{
int x1,y1;//箱子所在位置
int x2,y2;//人所在位置
int step;
void print(){
cout<<"step:"<<step<<" "<<x1+1<<" "<<y1+1<<" "<<x2+1<<" "<<y2+1<<endl;
}
};
int DFS(int rx,int ry)
{
if(rx==dfsx&&ry==dfsy) {
return 1;
}
vi[rx][ry]=1;
for(int i=0;i<4;i++){
int xx=rx+dir[i][0];int yy=ry+dir[i][1];
if(xx<0||xx>=M||yy<0||yy>=N||m[xx][yy]!=0||vi[xx][yy]) continue;
if(DFS(xx,yy)) {
return 1;
}
}
return 0;
}
queue<node> q;
int BFS(node b)
{
memset(vis,0,sizeof(vis));
while(!q.empty()){
q.pop();
}
q.push(b);
node tmp,t;
while(!q.empty()){
t=q.front();
q.pop();
//cout<<"out"<<" ";t.print();
if(t.x1==endx&&t.y1==endy) return t.step;
for(int i=0;i<4;i++){
tmp=t;
tmp.step++;
tmp.x1+=dir[i][0];
tmp.y1+=dir[i][1];
if(vis[t.x1][t.y1][i]==0&&tmp.x1>=0&&tmp.x1<M&&tmp.y1>=0&&tmp.y1<N&&m[tmp.x1][tmp.y1]==0){
memset(vi,0,sizeof(vi));
vi[tmp.x2][tmp.y2]=1;
dfsx=t.x1+to[i][0];dfsy=t.y1+to[i][1];
m[t.x1][t.y1]=2;
if(DFS(t.x2,t.y2)){
vis[t.x1][t.y1][i]=1;
tmp.x2=t.x1,tmp.y2=t.y1;
q.push(tmp);
//cout<<q.size()<<" "<<"in"<<" ";tmp.print();
}
m[t.x1][t.y1]=0;
}
}
}
return -1;
}
int main()
{
//freopen("data.in","r",stdin);
int t;
//cin>>t;
scanf("%d",&t);
int x,y;
while(t--){
memset(m,-1,sizeof(m));
//cin>>M>>N;
scanf("%d%d",&M,&N);
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
//cin>>m[i][j];
scanf("%d",&m[i][j]);
}
}
node b;
b.step=0;
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
if(m[i][j]==2) {b.x1=i,b.y1=j;m[i][j]=0;}
if(m[i][j]==4) {b.x2=i,b.y2=j;m[i][j]=0;}
if(m[i][j]==3) {endx=i,endy=j;m[i][j]=0;}
}
}
cout<<BFS(b)<<endl;
}
}
HDU1254--推箱子(BFS+DFS)的更多相关文章
- HDU1254:推箱子(bfs+dfs)
传送门 题意 给出一副图 0.空地1.墙2.箱子3.目的地4.人所在的位置 问最少几步能将箱子推到目的地 分析 这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,b ...
- HDU1254 推箱子(BFS) 2016-07-24 14:24 86人阅读 评论(0) 收藏
推箱子 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推 ...
- hdu.1254.推箱子(bfs + 优先队列)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 1254 推箱子 BFS
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目分析: 做这道题,感觉挺简单的,做着做着就错了20次, 我也是醉了, WA到吐的节奏啊! 思 ...
- 推箱子 BFS
[编程题] 推箱子 大家一定玩过“推箱子”这个经典的游戏.具体规则就是在一个N*M的地图上,有1个玩家.1个箱子.1个目的地以及若干障碍,其余是空地.玩家可以往上下左右4个方向移动,但是不能移动出地图 ...
- hdu - 1254 推箱子 (bfs+bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- 推箱子 (hdu1254)(bfs双重广搜)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission ...
- HDU 1254 推箱子(BFS)
Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不 ...
随机推荐
- Spring中pom文件所需节点
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...
- mybatis+mysql 返回主键
需求:使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法:在mapper中指定keyProperty属性,示例如下: <insert id="i ...
- css overflow规定元素溢出框将会发生什么
- PHP常见数组排序方法小结
1.简单数组排序 sort() 函数和rsort() 函数: 语法规则: bool sort(array &array [,int sort_flags] bool rsort(array & ...
- PythonError解决方案
# Pip Error pip install * error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visua ...
- ElasticSearch5.3安装IK分词器并验证
ElasticSearch5.3安装IK分词器 之前使用Elasticsearch安装head插件成功了,但是安装IK分词器却失败了.貌似是ElasticSearch5.0以后就不支持直接在elast ...
- Linux服务器应急事件溯源报告
Linux服务器应急事件溯源报告 小博博 · 2016/02/18 17:43 Author:Inn0team 0x00 目录 关于目标环境的中间进度检测报告 一:情况概述 二:取证情况 2.1 目标 ...
- 运维ipvsadm配置负载均衡
一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(r ...
- 使用油猴子 greasemonkey xx 百度 ...
百度首页在登录以后很恶心 没事弹出点垃圾新闻来污染眼球 搜索结果右下角的今日排行榜也是没事就出现垃圾的东西 所以让我们也xx一下百度.. // ==UserScript== // @name 清理百度 ...
- MySQL第三讲 一一一一 视图、触发器、函数、存储过程
1. 视图 1.1 视图前戏 我们之前讲有,临时表的概念. 现在我们创建一个临时表:select * from (select * from tb1 where id between 10 and 1 ...