推箱子 HDU1254 (bfs)
较难的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)的更多相关文章
- 推箱子 (hdu1254)(bfs双重广搜)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission ...
- HDU1254 推箱子(BFS) 2016-07-24 14:24 86人阅读 评论(0) 收藏
推箱子 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推 ...
- HDU 1254 推箱子(BFS)
Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不 ...
- HDU 1254 推箱子(BFS加优先队列)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others) Me ...
- 推箱子 hdu1254
推箱子 1 http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 2 http://acm.hzau.edu.cn/problem.php?id=1 ...
- suseoj 1212: 推箱子问题(bfs)
1212: 推箱子问题 时间限制: 1 Sec 内存限制: 128 MB提交: 60 解决: 13[提交][状态][讨论版][命题人:liyuansong] 题目描述 码头仓库是划分为n×m个格子 ...
- AcWing:172. 立体推箱子(bfs)
立体推箱子是一个风靡世界的小游戏. 游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示).易碎地面(用”E”表示).禁地(用”#”表示).起点(用”X”表示)或终点(用”O”表示). 你的 ...
- HDU1254:推箱子(bfs+dfs)
传送门 题意 给出一副图 0.空地1.墙2.箱子3.目的地4.人所在的位置 问最少几步能将箱子推到目的地 分析 这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,b ...
- hdu.1254.推箱子(bfs + 优先队列)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
随机推荐
- C++ error LNK2001
1.没有函数的实现部分 2.函数的头文件和实现部分不一致 3.缺库LIB.DLL 4.库H文件函数和库体不一致
- luogu P3924 康娜的线段树
题面传送门 我们可以画图找规律 这里没图,要看图可以去看M_sea dalao的题解(逃 可以发现单个节点\(i\)对答案的贡献为该节点的点权\(*\frac{1}{2^{dep_i}}\)(\(de ...
- 2017CCPC秦皇岛 L题One-Dimensional Maze&&ZOJ3992【模拟】
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3992 题意: 走迷宫,一个一维字符串迷宫,由'L'.'R'组成,分别 ...
- C# 进程的挂起与恢复
1. 源起: 仍然是模块化编程所引发的需求.产品经理难伺候,女产品经理更甚之~:p 纯属戏谑,技术方案与产品经理无关,芋头莫怪! VCU10项目重构,要求各功能模块以独立进程方式实现,比如:音视频转换 ...
- 关于出现Not an editor command: Bundle '**/*.vim'的解决方案【转】
转自:https://blog.csdn.net/YHM07/article/details/49717933 操作系统: $ uname -r 2.6.32-573.7.1.el6.x86_64 $ ...
- 嵌入式linux系统中,lsusb出现unable to initialize libusb: -99 解决办法 【转】
转自:http://cpbest.blog.163.com/blog/static/41241519201111575726966/ libusb是linux系统中,提供给用户空间访问usb设备的AP ...
- kmalloc vmalloc kzalloc malloc 和 get_free_page()【转】
转自:http://blog.csdn.net/hbhhww/article/details/7236695 kmalloc vmalloc kzalloc get_free_page()是内核空间申 ...
- Linux: 介绍make menuconfig中的每个选项含义【转】
转自:http://blog.csdn.net/gaoyuanlinkconcept/article/details/8810468 介绍make menuconfig中的每个选项含义 Linux 2 ...
- 程序执行的过程分析--【sky原创】
程序执行的过程: 比如我们要执行3 + 2 程序计数器(PC) = 指令地址 指令寄存器(IR) = 正在执行的命令 累加器(AC) = 临时存储体 那么实际上执行了三条指令 每条指令 ...
- javascript 添加行,删除行,datepicker获取当前日期和上一个月日期并设置格式,笔记
$(function () { getdatepicker(); today(); getPreMonth(); getdatetimepicker(); }); function today(){ ...