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的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不 ...
随机推荐
- 解决SQLPLUS ??? 显示的临时办法
错误现象为: 解决命令 export NLS_LANG=american_america.zhs16gbk
- set的常见用法
set的使用 set是什么 set是一个内部有序且不含重复元素的容器 用处 *使得元素自动有序 *去除重复元素 set的引入 # include <set> using namespace ...
- Nob常用命令
说明:此文件为常用的命令笔记 规则: .使用"[组名]"分组,如[linux] .使用"<标题一>"标示知识点,可用"<<二级 ...
- python3的base64编解码
使用python3的base64编解码实现字符串的简易加密解密 引言: 在一些项目中,接口的报文是通过base64加密传输的,所以在进行接口自动化时,需要对所传的参数进行base64编码,对拿到的响应 ...
- npm学习(二)之如何防止权限错误
如何防止权限错误 如果您在尝试全局安装包时看到EACCES错误,请阅读本章.如果更改安装npm的目录,通常可以避免此错误.要做到这一点,要么使用版本管理器重新安装npm(推荐)或手动更改npm的默认目 ...
- thinkphp5+layui多图片上传
准备资料 下载layui <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- vue打包时,assets目录 和static目录下文件的处理区别(nodeModule中插件源码修改后,打包后的文件应放在static目录)
为了回答这个问题,我们首先需要了解Webpack如何处理静态资产.在 *.vue 组件中,所有模板和CSS都会被 vue-html-loader 及 css-loader 解析,并查找资源URL.例如 ...
- vue.js(5)--事件修饰符
vue中的事件修饰符(.stop..prevent..self..capture..once) (1)实例代码 <!DOCTYPE html> <html lang="en ...
- DEV第三方控件的GalleryControl控件
1.获取选中的图片 List<GalleryItem> lstArray = gclImage.Gallery.GetCheckedItems(); 2.滚动到GalleryControl ...
- redis常见问题和解决方案
转载:https://www.cnblogs.com/aspirant/p/6820262.html [原创]那些年用过的Redis集群架构(含面试解析) redis常见问题和解决方案 持久化.主从问 ...