推箱子

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6416    Accepted Submission(s):
1834

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   |   We have carefully selected several
similar problems for you:  1180 1072 1372 1429 1728 
 
最开始写这道题的时候,想得很简单,如果箱子可以移动,那么移动的方向上箱子的前一点必须为空地,然后我想成了只要箱子移动的前一个点事空地箱子就可以朝这个方向移动。。。于是我写完了代码,过掉了超水的测试数据,然后华丽wa。。。仔细想了想,原来我没有考虑人的能不能走过来。。。。
咳咳,改变思想,重新出发,完全理解题意后,感觉有点复杂,不禁一阵头大,准备在网上搜个代码参考一下,了解了用四维数组标记的方法,顿时有了想法,完成了自己的代码。代码中定量很多,必须要细心。
先广搜箱子可以去的位置,然后深搜人是否能达到推箱子的这个点,记得将箱子的位置开成墙。
 
题意:中文题,很好理解。
 
附上代码:
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node
{
int x,y; //箱子的位置
int xx,xy; //人的位置
int t; //箱子动的格数
} s1,s2;
int f[][]= {,,,-,,,-,}; //方向变量
int map[][]; //记录地图
int vis[][][][]; //四维数组标记,同时记录箱子的位置和人的位置,去除重复的
int n,m; //边界
int a1,a2,b1,b2; //初始值
int flag[][],kk; bool xx(int a,int b)
{
if(a>=&&a<n&&b>=&&b<m&&map[a][b]!=) return true;
return false;
} void DFS(int nx,int ny,int mx,int my)
{
if(nx==mx&&ny==my) //如果从要到的点能搜到此时人的位置,则人可以走过来
{
kk=; //若能走来,标记为1
return;
}
for(int i=; i<&&!kk; i++)
{
int x=nx+f[i][];
int y=ny+f[i][];
if(xx(x,y)&&!flag[x][y])
{
flag[x][y]=; //走过的点标记为1
DFS(x,y,mx,my); //继续搜索
}
}
} void BFS()
{
queue<node> q;
while(!q.empty())
q.pop();
int nx,ny;
s1.x=a1; //初始化
s1.y=b1;
s1.xx=a2;
s1.xy=b2;
s1.t=;
vis[a1][b1][a2][b2]=; //开始状态标记为已出现
q.push(s1);
while(!q.empty())
{
s1=q.front();
q.pop();
if(map[s1.x][s1.y]==) //箱子到达指定位置后,队列循环结束
{
printf("%d\n",s1.t);
return;
}
for(int i=; i<; i++)
{
s2.x=s1.x+f[i][]; //箱子移动后的位置
s2.y=s1.y+f[i][];
nx=s1.x-f[i][]; //如果箱子能移动到那个位置,人必须能走到这个点
ny=s1.y-f[i][];
if(xx(s2.x,s2.y)&&xx(nx,ny)&&!vis[s2.x][s2.y][nx][ny])
//xx()函数判断是否超边界和是否是墙,箱子移动后的位置和人要到的位置都必须满足,并且此时这个状态是没有出现过的
{
memset(flag,,sizeof(flag)); //地图中所有不是墙的点都能走
flag[nx][ny]=flag[s1.x][s1.y]=; //箱子移动前的位置和人要到的位置都看做墙
kk=; //标记人是否能走过来
DFS(nx,ny,s1.xx,s1.xy); //深搜查询
if(kk) //如果人能走到
{
vis[s2.x][s2.y][nx][ny]=; //这个状态标记已出现
s2.xx=nx; //记录此时人到的位置
s2.xy=ny;
s2.t=s1.t+; //步数加一
q.push(s2); //入队列
}
}
}
}
printf("-1\n"); //如果不能到,则输出-1
return;
}
int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(vis,,sizeof(vis)); //标记全部初始化为0
for(i=; i<n; i++)
for(j=; j<m; j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==) //记录箱子的起始位置
{
a1=i;
b1=j;
}
if(map[i][j]==) //记录人的起始位置
{
a2=i;
b2=j;
}
}
BFS();
}
return ;
}

hdu 1254 推箱子(嵌套搜索,bfs中有dfs)的更多相关文章

  1. hdu 1254 推箱子(搜索)

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

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

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

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

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

  4. HDU 1254 推箱子 BFS

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

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

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

  6. HDU 1254 推箱子(BFS)

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

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

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

  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. opencv 图像基本操作

    目录:读取图像,获取属性信息,图像ROI,图像通道的拆分和合并 1.  读取图像 像素值返回:直接使用坐标即可获得, 修改像素值:直接通过坐标进行赋值 能用矩阵操作,便用,使用numpy中的array ...

  2. arcgis访问百度地图

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. Mac 电脑如何卸载 node

    因为刚入手「 Mac 」很多淫技还不懂,在一次使用 npm install 的时候安装出错,提示为 npm 与 node 的版本有问题,所以就想着卸载重新装一个版本. 但是因为刚使用「 Mac 」所以 ...

  4. [运维]VMware vSphere介绍 标签: 运维 2017-04-21 19:48 532人阅读 评论(17)

    大部分的程序员,应该是使用过vmware workstation的,我们用这款软件来创建虚拟机,满足我们学习或者工作的一些问题,今天介绍的是vmware家的另一款,不算是软件,比软件范围更大,VMwa ...

  5. 【转载】【软件安装】Source Insight 4.0常用设置

    1.Source Insight简介 Source Insight是一个面向软件开发的代码编辑器和浏览器,它拥有内置的对C/C++, C#和Java等源码的分析,创建并动态维护符号数据库,并自动显示有 ...

  6. SQLServer数据库(二)

    数据库设计:就是将数据库中的数据库实体及这些数据库实体之间的关系,进行规划和结构化的过程. 项目开发过程: 需求分析 概要设计 详细设计 代码编写 运行测试 打包发行 数据库的系统分析基本步骤:收集信 ...

  7. Directx11教程(19) 画一个简单的地形

    原文:Directx11教程(19) 画一个简单的地形       通常我们在xz平面定义一个二维的网格,然后y的值根据一定的函数计算得到,比如正弦.余弦函数的组合等等,可以得到一个看似不错的地形或者 ...

  8. yum install mysql-devel

    linux系统在装mysql相关的包时要先装mysql-deval,这个包包含mysql的相关配置和环境组件 执行yum install mysql-deval

  9. NEFU 118 n!后面有多少个0【数论】

    http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=118 求n!后面有多少个0(1<=n<=1000000000) ...

  10. 利用IDEA构建springboot应用-构建好SpringBoot + SSM 框架

    一. 创建项目 选择 Spring Initiallizr 添加最基本的几个依赖 Web,MySQL,MyBatis,其他需求可以后续再添加 ; 数据库选择了 MySQL 二. 配置数据源 数据源中存 ...