推箱子 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 ...
随机推荐
- leetCode- 472. Concatenated Words
因为每个组合的字符串,至少要有3个index. 起点,中间拼接点,结点.所以可以将字符串分解为子字符串,判断子字符串是否存在.但是,后面字符串的存在必须要在前面字符串已经存在基础上判断. class ...
- static extern
/*主程序在a.c*/ //a.c #include <stdio.h> #include "b.h" main(){ printf ("%d\n" ...
- [转]gcc -ffunction-sections -fdata-sections -Wl,–gc-sections 参数详解
背景 有时我们的程序会定义一些暂时使用不上的功能和函数,虽然我们不使用这些功能和函数,但它们往往会浪费我们的ROM和RAM的空间.这在使用静态库时,体现的更为严重.有时,我们只使用了静态库仅有的几个功 ...
- DSO windowed optimization 代码 (1)
这里不想解释怎么 marginalize,什么是 First-Estimates Jacobian (FEJ).这里只看看代码,看看Hessian矩阵是怎么构造出来的. 1 优化流程 整个优化过程,也 ...
- SSH开发环境搭建
断断续续学习hibernate也有一段时间了,在这里研究一下SSH开发环境的搭建过程,自己简单的搭建一个SSH的开发环境.采用maven搭建. 0.项目结构: 1.导包:(maven项目) pom.x ...
- stderr 和stdout
今天又查了一下fprintf,其中对第一个参数stderr特别感兴趣. int fprintf(FILE *stream,char *format,[argument]): 在此之前先区分一下:pri ...
- HTML学习笔记04-样式
HTML<style>属性 style属性的作用: 提供了一种改变所有HTML元素样式的通用方法 background-colco属性为元素定义了背景颜色: <!DOCTYPE HT ...
- Springboot分模块开发
这是个spring cloud项目,service-base:基础服务:service-config:配置中心:service-entity:实体类: service-gateway:服务网关:ser ...
- css怎么让页面上的内容不能被选中
body{ -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-se ...
- CSS和DIV
DIV主要就是结合CSS使用来对网页进行布局: CSS可以通过单独建立一个.css的文件来使用<link type="text/css" href="1.css& ...