题目传送门

首先说明我这个代码和lyd的有点不同:可能更加复杂

 既然要求以箱子步数为第一关键字,人的步数为第二关键字,那么我们可以想先找到箱子的最短路径。但单单找到箱子的最短路肯定不行啊,因为有时候不能被推动,怎样确定一条既满足最短又满足可行的箱子路径呢,其实这就是一种有限制的BFS。

 对于箱子:

  设现在的位置为x,y,扩展方向为dx,dy,将要到达的下一个位置为x+dx,y+dy

 check它是否可行:

1.不越界。

2.之前没有走过。

3.不能走到“#”上。

4.人能够从当前站立的位置到达(x-dx,y-dy)。

诶,对了,第4个条件实际上就是对于人的bfs。


  因此,这就是一个双重bfs。(数据范围r,c<=20可行!)

  那么对于人的bfs,有什么限制条件:当然最重要的不能走到箱子现在的位置(x,y)上

  还有记录路径,每次回溯和逆推。

  嗯,具体细节看代码吧(不想打字了)

//Pushing Boxes -POJ1475
//最长代码 祭 AC 329ms
//开始没有数组清零WA
//然后数组开大了,TLE
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#define de system("pause");
#define re register int
using namespace std;
int r,c,ans,ansx,ansy;
char s[][];
int per[],box[];
int dx[]={-,,,};
int dy[]={,,-,};
char ren[]={'n','s','w','e'};
char xiang[]={'N','S','W','E'};
bool bz[][],flag[][];
struct node{
int x,y,step;
int man[];
node(int xx,int yy,int stepp,int mx,int my)
{
x=xx,y=yy,step=stepp;
man[]=mx,man[]=my;
}
};
struct node2{
int x,y;
node2(int xx,int yy)
{
x=xx;
y=yy;
}
};
queue<node> q;
queue<node2> p;
struct hp{
int px,py,d;
int cnt;
int path[];
}fix[][],walk[][];
//fix主要记录箱子的路径,walk主要记录人的路径。
inline bool bfs(int bx,int by,int aimx,int aimy,int nowx,int nowy)
{
memset(flag,,sizeof flag);
memset(walk,,sizeof walk);
while(p.size()) p.pop();
p.push(node2(nowx,nowy));
if(nowx==aimx&&nowy==aimy) return ;
flag[nowx][nowy]=;
while(!p.empty())
{
node2 now=p.front();
int x=now.x,y=now.y;
p.pop();
for(re i=;i<=;++i)
{
int cx=x+dx[i],cy=y+dy[i];
if(cx<||cx>r||cy<||cy>c)continue;
if(flag[cx][cy])continue;
if(s[cx][cy]=='#')continue;
if(cx==bx&&cy==by)continue;
p.push(node2(cx,cy));
flag[cx][cy]=;
walk[cx][cy].px=x;
walk[cx][cy].py=y;
walk[cx][cy].d=i;
if(cx==aimx&&cy==aimy)
{
return ;
}
}
}
return ;
}
inline bool check(int x,int t1,int y,int t2,int standx,int standy)
{
if(x+t1<||x+t1>r||y+t2<||y+t2>c)return ;
if(bz[x+t1][y+t2]) return ;
if(s[x+t1][y+t2]=='#')return ;
if(bfs(x,y,x-t1,y-t2,standx,standy))//如果人能够移动
{
int tx=x-t1,ty=y-t2;//从目标回溯到初位置
while(tx!=standx||ty!=standy)
{
hp temp=walk[tx][ty];
fix[x+t1][y+t2].path[++fix[x+t1][y+t2].cnt]=walk[tx][ty].d;
tx=temp.px;
ty=temp.py;
}//在这里顺便就把这一次转移路径记录下来
return ;
}
return ;
}
inline void Bfs()
{
while(!q.empty())
{
node now=q.front();
int x=now.x,y=now.y,step=now.step;
int man_x=now.man[],man_y=now.man[];
q.pop();
for(re i=;i<=;++i)
{
int cx=x+dx[i],cy=y+dy[i];
if(check(x,dx[i],y,dy[i],man_x,man_y))
{
q.push(node(cx,cy,step+,x,y));
bz[cx][cy]=;
fix[cx][cy].px=x,fix[cx][cy].py=y;
fix[cx][cy].d=i;
if(s[cx][cy]=='T')
{
if(step+<ans)
{
ans=step+;
ansx=cx,ansy=cy;
}
}
}
}
}
} char shuchu[];
int rt=;
inline void print()
{
int num=;
int prx=ansx;
int pry=ansy;
int tt=;
while((prx!=box[])||(pry!=box[]))
{
hp ne=fix[prx][pry];
shuchu[++num]=xiang[ne.d];
for(re i=;i<=ne.cnt;++i)
{
shuchu[++num]=ren[ne.path[i]];
}
prx=ne.px;
pry=ne.py;
}
printf("Maze #%d\n",++rt);
for(re i=num;i>=;--i) cout<<shuchu[i];
puts("");
}
int main()
{
while()
{
while(q.size())q.pop();
memset(bz,,sizeof bz);
// memset(shuchu,0,sizeof shuchu);
memset(fix,,sizeof fix);
// memset(walk,0,sizeof walk);
ans=1e6;
scanf("%d%d",&r,&c);
if(r==&&c==)break;
for(re i=;i<=r;++i){
scanf("%s",s[i]+);
for(re j=;j<=c;++j){
if(s[i][j]=='B')box[]=i,box[]=j,bz[i][j]=;
if(s[i][j]=='S')per[]=i,per[]=j;
}
}
q.push(node(box[],box[],,per[],per[]));
Bfs();
if(ans==1e6)
{
printf("Maze #%d\n",++rt);
puts("Impossible.");
}
else print();
puts("");
}
return ;
}

Add/

1.关于POJ的special judge可能有点毒瘤,所以建议按照'N','S','W','E'的方向进行搜索。

2.数组不要开大了。

3.输出两个换行......

Pushing Boxes(广度优先搜索)的更多相关文章

  1. POJ1475 Pushing Boxes(双搜索)

    POJ1475 Pushing Boxes  推箱子,#表示墙,B表示箱子的起点,T表示箱子的目标位置,S表示人的起点 本题没有 Special Judge,多解时,先最小化箱子被推动的次数,再最小化 ...

  2. [poj P1475] Pushing Boxes

    [poj P1475] Pushing Boxes Time Limit: 2000MS   Memory Limit: 131072K   Special Judge Description Ima ...

  3. 图的广度优先搜索(BFS)

    把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...

  4. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

  5. 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较

    广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...

  6. poj 1475 || zoj 249 Pushing Boxes

    http://poj.org/problem?id=1475 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249 Pushin ...

  7. ACM题目————图的广度优先搜索

    题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结 ...

  8. SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  9. HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

随机推荐

  1. 用poolmon来查找内存泄露

    用poolmon来查找内存泄露 poolmon C:\WinDDK\7600.16385.1\tools\Other\i386\poolmon.exegflags     C:\WinDDK\7600 ...

  2. nginx mysqlnd驱动引擎提升mysql性能

    nginx mysqlnd驱动引擎提升mysql性能 前期要安装 mysql mysqli pdo_mysql libiconv 1 先去PHP官网下个 php-5.6.29.tar.gz wget ...

  3. ThinkPHP5 使用 JWT 进行加密

    使用 Github 的 firebase\JWT - 使用 Composer 安装此扩展 - 代码示例 <?php /** * [InterCommon-接口公用] * @Author Rain ...

  4. drf面试题及总结

    drf面试题及总结 1.什么是前后端分离 2.什么是restful规范 3.模拟浏览器进行发送请求的工具 4.查找模板的顺序 5.什么是drf组件 6.drf组件提供的功能 7.drf继承过哪些视图类 ...

  5. 复习:C语言基础知识1

    占位符: %d, %i,代表整数,%f-浮点,%s,字符串,%c,char. %p 指针,%fL 长long,%e科学计数,%g 小数或科学计数. C语言中的格式占位符: %a,%A 读入一个浮点值( ...

  6. golang socket与Linux socket比较分析

    在posix标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带runtime的跨平台编程语言,Go中提供给开发者的socket API是建立在操作系统原生socket ...

  7. Java中使用OpenSSL生成公钥私钥进行数据加解密

    当前使用的是Linux系统,已经安装OpenSSL软件包. 一.使用OpenSSL来生成私钥和公钥1.执行命令openssl version -a 验证机器上已经安装openssl $ openssl ...

  8. UDP比TCP好用的优势

    网络带宽环境变好 在2007年至2015年间,网络的带宽飞速发展,从1.5Mbps的带宽增加到5.1Mbps的带宽,足足增加了4倍,网络环境快速.稳定,所以UDP的丢包率 下降至5%以下,越来越好的网 ...

  9. intellij idea 修改背景保护色&&修改字体&&快捷键大全

    intellij idea 修改背景保护色&&修改字体&&快捷键大全 原创 2013年11月22日 18:00:07 90176 最近Idea比较流行,Eclipse因 ...

  10. eclipse的debug模式的F5,F6按键失灵

    在使用eclipse Mars.1 Release (4.5.1)开发过程中,发现debug模式下的快捷键无法使用,全部失效了.秉持坚决自己解决绝不求人的态度我艰苦的在度娘上寻求解决办法,有的说是快捷 ...