题目传送门

首先说明我这个代码和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. word2vec学习总结

    目录 1.简介 2.从统计语言模型开始 2.1序列概率模型 2.2 N元统计模型 3.深度序列模型 3.1神经概率模型 3.2 one-hot向量表示法 3.3 word2vec 3.4word2ve ...

  2. Centos 6.X查看和设置时间时区

    Centos 6.X系列操作系统的修改时区和时间的方法. 一.查看Centos的时区和时间 1.使用date命令查看Centos时区 [root@VM_centos ~]# date -R Mon, ...

  3. 【RabbitMQ学习之二】RabbitMQ四种交换机模式应用

    环境 win7 rabbitmq-server-3.7.17 Erlang 22.1 一.概念1.队列队列用于临时存储消息和转发消息.队列类型有两种,即时队列和延时队列. 即时队列:队列中的消息会被立 ...

  4. 【07月03日】A股ROE最高排名

    个股滚动ROE = 最近4个季度的归母净利润 / ((期初归母净资产 + 期末归母净资产) / 2). 查看更多个股ROE最高排名 兰州民百(SH600738) - ROE_TTM:86.45% - ...

  5. 依赖注入(DI)与控制反转(IOC)基础知识

    依赖注入(DI)与控制反转(IOC)基础知识 一.什么是依赖注入? 依赖注入英文是Dependcy Injection简写DI,依赖注入会将所依赖的对象自动交由目标对象使用,而不是让对象自己去获取. ...

  6. cmake 配置

    罗列一下cmake常用的命令.CMake支持大写.小写.混合大小写的命令. 1. 添加头文件目录INCLUDE_DIRECTORIES 语法:include_directories([AFTER|BE ...

  7. 深入理解AQS

    前记 在看JUC中并发相关的源码时经常看到AQS的身影,这到底是个什么鬼?必须要一探究竟. 一. AQS背景了解 JUC包中的锁,包括: Lock接口,ReadWriteLock接口,LockSupp ...

  8. Scala 函数式编程

    将函数赋值给变量 // Scala中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量 // Scala的语法规定,将函数赋值给变量时,必须在函数后面加上空格和下划线 def ...

  9. js遍历数组和数组对象

    <script> //----------------for用来遍历数组对象-- var i,myArr = [1,2,3]; for (var i = 0; i < myArr.l ...

  10. Codeforces Round #580 (Div. 1)

    Codeforces Round #580 (Div. 1) https://codeforces.com/contest/1205 A. Almost Equal 随便构造一下吧...太水了不说了, ...