传送门:

http://acm.hdu.edu.cn/showproblem.php?pid=1254

推箱子

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

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:  1253 1072 1240 1372 1429 
 
 
分析:
BFS加优先队列

从人为起点开始bfs,如果人走的下一步是箱子所在的坐标,说明找到了箱子,

箱子的坐标为当前所搜方向上人的坐标前进一格(就是推一格箱子,箱子前进的方向和人前进的方向是一致的),

判断箱子是否到达了目的地,如果是则输出箱子移动的最少步数,到不了就输出-1。

应该按照所走步数多少决定出队列顺序,所以用优先队列处理下。

(人从起点找箱子是不计数的)

需要注意的地方:

1.要判断人的位置是不是合法:有没有越界或者该位置是墙

2.要判断能不能推箱子:也就是人有没有找到箱子,比较一开始人和箱子是由距离的,

如果人走的下一步是箱子所在的坐标,说明找到了箱子

3.要判断箱子位置的合法性:越界或者该点是墙

具有做法:

先将箱子位置和人位置入队

1.如果箱子到了指定位置,直接输出步数

2.四个方向搜,先判断人的下一步位置是否合法,合法的话让人一直走,走到人能推箱子的时候

,在判断推导箱子之后箱子的位置合不合法,合法的话步数加1

具体请参考代码:

code:

#include<bits/stdc++.h>
using namespace std;
int dir[][]= {,,,,,-,-,}; //方向数组
#define max_v 12
int n,m;
int G[max_v][max_v];//存图
int vis[max_v][max_v][max_v][max_v];
struct node
{
int x,y;//人的坐标
int bx,by;//箱子的坐标
int step;//推箱子的步数
bool friend operator<(const node &a, const node &b)
{
//必须优先队列,步数小优先ye1js
return a.step>b.step;
} } start; //起点
bool check_person(node next)//判断人的位置是否合法
{
if(next.x>=&&next.x<=n&&next.y>=&&next.y<=m&&G[next.x][next.y]!=)//没有越界且不是墙
return true;
else
return false;
}
bool check_box1(node next,node t)//判断能不能推箱子
{
if(next.x==t.bx&&next.y==t.by)//如果人走的下一步是箱子所在的坐标,说明找到了箱子
return true;
else
return false;
}
int check_box2(int tbx,int tby)//判断箱子坐标的合法性
{
if(tbx>=&&tbx<=n&&tby>=&&tby<=m&&G[tbx][tby]!=)//越界或者墙
return true;
else
return false;
}
void bfs()
{
node next,t;
priority_queue<node>q;
memset(vis,,sizeof(vis));//标志位置空
//队列初始化
vis[start.x][start.y][start.bx][start.by]=;
start.step=;
q.push(start); while(!q.empty())
{
t=q.top();
q.pop();
if(G[t.bx][t.by]==)//箱子到了指定位置
{
cout<<t.step<<endl;
return ;
} for(int i=; i<; i++)
{
next.x=t.x+dir[i][];//人的下一步
next.y=t.y+dir[i][]; if(check_person(next))//判断人的下一步位置是否合法
{
next.bx=t.bx;//不能推箱子时,箱子的坐标
next.by=t.by;
next.step=t.step; if(check_box1(next,t))//能推箱子
{
int tbx=t.bx+dir[i][];//推动箱子之后,箱子的坐标
int tby=t.by+dir[i][]; if(check_box2(tbx,tby))//判断推导箱子之后箱子坐标的合法性,合法则更新坐标
{
next.bx=tbx;
next.by=tby;
next.step++;//步数加1
}
}
if(vis[next.x][next.y][next.bx][next.by]==)//该情况没有搜过,则入队,开始搜
{
vis[next.x][next.y][next.bx][next.by]=;
q.push(next);
}
}
}
}
cout<<"-1"<<endl;
return ;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
cin>>G[i][j];
if(G[i][j]==)
{
start.x=i;//找到人在坐标
start.y=j;
G[i][j]=;
}
if(G[i][j]==)
{
start.bx=i;//找到箱子的坐标
start.by=j;
G[i][j]=;
}
}
}
bfs();
}
return ;
}

HDU 1254 推箱子(BFS加优先队列)的更多相关文章

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

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

  2. HDU 1254 推箱子 BFS

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

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

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

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

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

  5. HDU 1254 推箱子(BFS)

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

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

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

  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. C++11并发编程:async,future,packaged_task,promise

    一:async std::async:用于创建异步任务,可以代替创建线程,函数原型:async(std::launch::async | std::launch::deferred, f, args. ...

  2. STM32F407使用MFRC522射频卡调试及程序移植成功

    版权声明:转载请注明出处,谢谢 https://blog.csdn.net/Kevin_8_Lee/article/details/88865556 或  https://www.cnblogs.co ...

  3. 防盗链与springboot代理模式(图片文件转发)

    在搭建自己的博客网站的时候,很有可能要引入一些外部图片,毕竟多数人最开始不是在自己的平台上写博客. 因某种需要,搬运自己以前写的博客到自己的网站时,在图片这一步可能会出现问题,无法显示.其中往往就是防 ...

  4. 【LDAP】ldap目录服务的命名模型

    ldap的命名模型 命名模型规定了在目录中如何组织和表示条目 1.   目录信息树(DIT) 目录信息树有点类似于DNS的结构.每一个条目都有自己的父条目(因为主条目的父条目是top,所以这句话是成立 ...

  5. Python下Mysql数据连接池——单例

    # coding:utf-8 import threading import pymysql from DBUtils.PooledDB import PooledDB from app.common ...

  6. windows下libcurl+openssl编译与使用配置

    之前使用过libcurl, 编译也是最简单的版本, 不需要openssl, 即不需要支持https, 所以编译和使用都很正常. 但要使用openssl就很麻烦了, 我花了差不多两天去编译和调用, 记录 ...

  7. IE9下JQuery发送ajax请求失效

    最近在做项目的时候,测试PC端网页,在IE9下会失效,不能正常的发送POST请求,经过仔细的排查,发现是IE9下JQuery发送ajax存在跨域问题. 目前有两种解决方案:   解决方案一: 设置浏览 ...

  8. My eclipse jdk unbound的解决

    project --> properties --> java build path --> 双击出错的jdk --> alternate jre --> install ...

  9. struts2的基本配置

    1.package标签下主要的点在namespace和name,extend上 extend 一般继承自struts-default.xml下,继承其拦截器及一些功能,这个已在本人的拦截器一文中有讲到 ...

  10. 【数据库】1.0 MySQL入门学习(一)——常识性知识

    1.0 什么是MySQL(官方发音 My Ess Que Ell)? 是一个快速.多线程.多用户和强壮的SQL数据库服务器,SQL是世界上最流行的标准化数据库语言. 名字来源:共同创办人Monty W ...