较难的bfs

有两种方法做

一种双重bfs:

主bfs是箱子   还要通过dfs判断人是否能到箱子后面

用inmap函数的好处。。

箱子要用三位数组来标记  因为箱子可以回到原来到过的地方  因为推的方向不同 (第三位来表示方向)

并且地图无需改变(一些人在结构体里自带一份地图)

这题箱子的位置 对人来是是墙 不可越过  用设置vis2来实现  非常巧妙

用全局flag来代替dfs中的bool 方便很多 也不容易出错

#include<bits/stdc++.h>
using namespace std; int n,m,m1[][],vis[][][],vis2[][];
int sx,sy,ex,ey,rx1,ry1;
int dx[]={,,,-};
int dy[]={,,-,};
int flag=; struct node
{
int x,y,d,rx,ry;
node(int x=,int y=,int d=,int rx=,int ry=):x(x),y(y),d(d),rx(rx),ry(ry){}
}; bool inmap(int a,int b)
{
if(a<||a>n||b<||b>m||m1[a][b]==)
return false;
return true; } void bfs1( int sx, int sy,int ex,int ey)
{ if(sx==ex&&sy==ey) {flag=;return ;}
if(flag==)return;//值得学习
for(int i=;i<;i++)
{ if(vis2[sx+dx[i]][sy+dy[i]]==&&inmap(sx+dx[i],sy+dy[i]))
{
//printf("%d %d \n",sx+dx[i],sy+dy[i]);
vis2[sx+dx[i]][sy+dy[i]]=;
bfs1(sx+dx[i],sy+dy[i],ex,ey); } } } void bfs()
{ memset(vis,,sizeof(vis));
memset(vis2,,sizeof(vis2));
node u(sx,sy,,rx1,ry1);
queue<node>q;
q.push(u); while(!q.empty())
{ u=q.front();q.pop();
// printf("%d %d %d\n",u.x,u.y,u.d);
if(u.x==ex&&u.y==ey){printf("%d\n",u.d);return;} for(int i=;i<;i++)
{
node v(u.x+dx[i],u.y+dy[i],u.d+,u.rx,u.ry);//用自加是错的 if(inmap(u.x-dx[i],u.y-dy[i])&&inmap(v.x,v.y)&&vis[v.x][v.y][i]==)
{
flag=;
memset(vis2,,sizeof(vis2));
vis2[u.rx][u.ry]=;
vis2[u.x][u.y]=;//非常关键!!!箱子也是障碍!!!
bfs1(u.rx,u.ry,u.x-dx[i],u.y-dy[i]); if(flag)
{
vis[v.x][v.y][i]=;
v.rx=u.x-dx[i];
v.ry=u.y-dy[i];
q.push(v);
}
}
}
}
printf("-1\n");return ; }
int main()
{
int cas;scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
// printf("%d %d\n",n,m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
scanf("%d",&m1[i][j]);
if(m1[i][j]==){ex=i;ey=j;}
if(m1[i][j]==){sx=i;sy=j;}
if(m1[i][j]==){rx1=i;ry1=j;} }
// printf("%d %d\n",sx,sy);
bfs(); } return ;
}

还有一种方法是一次BFS  优先队列   用四维数组来标记人和箱子的座标 然后人疯狂乱走   如果人走到了箱子上了  就相当于推动了一次

回顾:

一定要用优先队列   不然的话是以人走的步数为基准

还有一定要注意  队列里面的优先级是反的!!!!

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 9
#define inf 0x3f3f3f3f int dx[]={,,,-};
int dy[]={,-,,};
int sx,sy,ex,ey,rx,ry;
int n,m;
int mp[N][N]; bool inmap(int x,int y)
{
return x>=&&x<=n&&y>=&&y<=m;
} struct node
{
int x,y,d,rx,ry;
bool operator <(const node &h)const{
return d>h.d;
}
}; int vis[N][N][N][N]; void bfs()
{
memset(vis,,sizeof vis);
node u,v;
u.x=sx;
u.y=sy;
u.d=;
u.rx=rx;
u.ry=ry;
priority_queue<node>q;
q.push(u);
vis[sx][sy][rx][ry]=;
while(!q.empty())
{
u=q.top();q.pop(); if( mp[u.x][u.y]== ){printf("%d\n",u.d);return ;} for(int i=;i<;i++)
{
v=u;
v.rx+=dx[i];
v.ry+=dy[i];
if( inmap(v.rx,v.ry) &&mp[v.rx][v.ry]!=)
{
if(v.rx==v.x&&v.ry==v.y&& inmap(v.x+dx[i],v.y+dy[i] )&&mp[v.x+dx[i]][v.y+dy[i]]!= )
{
v.x+=dx[i];
v.y+=dy[i];
v.d+=;
}
if(!vis[v.x][v.y][v.rx][v.ry] )
{
q.push(v);
vis[v.x][v.y][v.rx][v.ry]=;
}
}
}
}
printf("-1\n");
} int main()
{
int cas;cin>>cas;
while(cas--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
scanf("%d",&mp[i][j]);
int t=mp[i][j];
if(t==){rx=i;ry=j;}
if(t==){sx=i;sy=j;}
}
bfs();
}
return ;
}

推箱子 HDU1254 (bfs)的更多相关文章

  1. 推箱子 (hdu1254)(bfs双重广搜)

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

  2. HDU1254 推箱子(BFS) 2016-07-24 14:24 86人阅读 评论(0) 收藏

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

  3. HDU 1254 推箱子(BFS)

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

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

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

  5. 推箱子 hdu1254

    推箱子 1  http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 2  http://acm.hzau.edu.cn/problem.php?id=1 ...

  6. suseoj 1212: 推箱子问题(bfs)

    1212: 推箱子问题 时间限制: 1 Sec  内存限制: 128 MB提交: 60  解决: 13[提交][状态][讨论版][命题人:liyuansong] 题目描述 码头仓库是划分为n×m个格子 ...

  7. AcWing:172. 立体推箱子(bfs)

    立体推箱子是一个风靡世界的小游戏. 游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示).易碎地面(用”E”表示).禁地(用”#”表示).起点(用”X”表示)或终点(用”O”表示). 你的 ...

  8. HDU1254:推箱子(bfs+dfs)

    传送门 题意 给出一副图 0.空地1.墙2.箱子3.目的地4.人所在的位置 问最少几步能将箱子推到目的地 分析 这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,b ...

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

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

随机推荐

  1. Hadoop mapreduce执行过程涉及api

    资源的申请,分配过程略过,从开始执行开始. mapper阶段: 首先调用默认的PathFilter进行文件过滤,确定哪些输入文件是需要的哪些是不需要的,然后调用inputFormat的getSplit ...

  2. python中修改工作目录

  3. Linux cache 缓存过大

    linux cache 缓存过大 : 除重启服务 之外:直接释放内存方式之一: 修改配置释放cached内存: echo > /proc/sys/vm/drop_caches

  4. 【BZOJ4826】【HNOI2017】影魔(扫描线,单调栈)

    [BZOJ4826][HNOI2017]影魔(扫描线,单调栈) 题面 BZOJ 洛谷 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他 ...

  5. POJ3436 ACM Computer Factory【EK算法】

    题意: 每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分.且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大 ...

  6. tomcat顺序图摘要

    1.Connector 处理一次请求顺序图 2.Context 和 wrapper 的处理请求时序图 3. 参考: https://www.ibm.com/developerworks/cn/java ...

  7. Java调整JVM内存大小——(八)

    JVM内存大小是有限的,有的时候程序过大时候会导致超出最大内存,产生下面异常: Exception in thread "main" java.lang.OutOfMemoryEr ...

  8. Dubbo配置参数的优先级

    总结为: 1).Java运行时虚拟机参数 eg:-Ddubbo.protocol.port=20880 2).dubbo.xml || application.properties(SpringBoo ...

  9. Three.js基础探寻一

    1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SV ...

  10. 嵌入式系统C编程之错误处理

    前言 本文主要总结嵌入式系统C语言编程中,主要的错误处理方式.文中涉及的代码运行环境如下: 一  错误概念 1.1 错误分类 从严重性而言,程序错误可分为致命性和非致命性两类.对于致命性错误,无法执行 ...