POJ1475 Pushing Boxes

 推箱子,#表示墙,B表示箱子的起点,T表示箱子的目标位置,S表示人的起点

本题没有 Special Judge,多解时,先最小化箱子被推动的次数,再最小化人移动的步数。若仍有多条路线,则按照N、S、W、E的顺序优先选择箱子的移动方向(即先上下推,再左右推)。在此前提下,再按照n、s、w、e的顺序优先选择人的移动方向(即先上下动,再左右动)。

  • 每个阶段的状态包括人的位置,箱子的位置,由于每次在移动箱子之后,人的位置一定位于箱子之前的位置,所以可以将每次箱子刚刚移动后,箱子与人的位置的状态打包在一起,bfs中对于取出的队头,枚举箱子的下一个位置,然后再用一个bfs求出人由现在的位置到应该在的位置的最短步数即可
  • Impossible后面没打'.',调了一上午qwq
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <queue>
#include <iostream>
#include <cmath>
using namespace std; #define N 26
#define res int
#define inf 0x3f3f3f3f const int dx[]={-,,,},dy[]={,,-,};
const char A[]={'N','S','W','E'},B[]={'n','s','w','e'};
int n,m;
char s[][]; string tmp;
struct node {
int x,y,px,py;
string ans;
}; inline bool valid(int x,int y){
return (x>= && x<=n && y>= && y<=m && s[x][y]!='#');
} bool bfs2(node a,node b)
{
tmp="";
node st;
st.x=a.px;
st.y=a.py;
st.ans="";//人的初始位置
queue<node> q;
q.push(st);
bool v[][];
memset(v,,sizeof(v));
while(q.size())
{
node now=q.front(); q.pop();
if(now.x==a.x && now.y==a.y)
{ tmp=now.ans; return true; }
for(res k= ; k< ; k++)
{
node nxt;
nxt.x=now.x+dx[k];
nxt.y=now.y+dy[k];
if(!valid(nxt.x,nxt.y)||v[nxt.x][nxt.y]) continue;
if(nxt.x==b.x && nxt.y==b.y) continue;
v[nxt.x][nxt.y]=;
nxt.ans=now.ans+B[k];
q.push(nxt);
}
}
return false;
}
node st;
string bfs1()
{
st.x=st.y=st.px=st.py=-;
st.ans="";
for(res i= ; i<=n ; i++)
for(res j= ; j<=m ; j++)
if(s[i][j]=='B')
st.x=i,st.y=j,s[i][j]='.';
else if(s[i][j]=='S')
st.px=i,st.py=j,s[i][j]='.';
queue<node> q;
int v[][][];
memset(v,,sizeof(v));
q.push(st);
string ans="Impossible.";
int cnt_box=inf,cnt_man=inf;
while(q.size())
{
node now=q.front(); q.pop();
if(s[now.x][now.y]=='T')
{
int cntb();
for(res i= ; i<now.ans.length() ; i++)
if(now.ans[i]>'A' && now.ans[i]<'Z') cntb++;
if(cntb<cnt_box || (cntb==cnt_box&& now.ans.length()-cntb<cnt_man))
cnt_box=cntb,cnt_man=now.ans.length()-cntb,ans=now.ans;
continue;
}
for(res k= ; k< ; k++)
{
node nxt; nxt.x=now.x+dx[k]; nxt.y=now.y+dy[k];
if(!valid(nxt.x,nxt.y) || v[nxt.x][nxt.y][k]) continue; node pre=now;
if(k==) pre.y=now.y-;
else if(k==) pre.y=now.y+;
else if(k==) pre.x=now.x-;
else pre.x=now.x+;//人的移动,此处x,y表示目标位置
v[nxt.x][nxt.y][k]=;
if(!valid(pre.x,pre.y) || !bfs2(pre,now)) continue;
nxt.ans=now.ans+tmp;
nxt.ans+=A[k];
nxt.px=now.x;
nxt.py=now.y;
q.push(nxt);
}
}
return ans;
} int main()
{
int Case();
while(scanf("%d %d",&n,&m)&&n&&m)
{
Case++;
for(res i= ; i<=n ; i++) cin>>(s[i]+);
cout<<"Maze #"<<Case<<endl;
cout<<bfs1()<<endl<<endl;
}
return ;
}

POJ1475 Pushing Boxes(双搜索)的更多相关文章

  1. poj1475 Pushing Boxes[双重BFS(毒瘤搜索题)]

    地址. 很重要的搜索题.★★★ 吐槽:算是写过的一道码量比较大的搜索题了,细节多,还比较毒瘤.虽然是一遍AC的,其实我提前偷了大数据,但是思路还是想了好长时间,照理说想了半小时出不来,我就会翻题解,但 ...

  2. POJ1475(Pushing Boxes)--bbffss

    题目在这里 题目一看完就忙着回忆童年了.推箱子的游戏. 假设只有一个箱子.游戏在一个R行C列的由单位格子组成的区域中进行,每一步, 你可以移动到相邻的四个格子中的一个,前提是那个格子是空的:或者,如果 ...

  3. poj1475 -- Pushing Boxes

    这道题其实挺有趣 的,这让我想起小时候诺基亚手机上的推箱子游戏(虽然一点也不好玩) (英文不好-->)  题意翻译: 初始人(S),箱子(B),目的地(T)用人把箱子推到 T最小步数及其路径(满 ...

  4. POJ-1475 Pushing Boxes (BFS+优先队列)

    Description Imagine you are standing inside a two-dimensional maze composed of square cells which ma ...

  5. poj1475 Pushing Boxes(BFS)

    题目链接 http://poj.org/problem?id=1475 题意 推箱子游戏.输入迷宫.箱子的位置.人的位置.目标位置,求人是否能把箱子推到目标位置,若能则输出推的最少的路径,如果有多条步 ...

  6. POJ1475 Pushing Boxes(BFS套BFS)

    描述 Imagine you are standing inside a two-dimensional maze composed of square cells which may or may ...

  7. POJ1475 Pushing Boxes 华丽丽的双重BFS

    woc累死了写了两个半小时...就是BFS?我太菜了... 刚开始以为让人预先跑一遍BFS,然后一会儿取两节加起来就好了,结果发现求出来的最短路(就是这个意思)会因箱子的移动而变化....我死了QWQ ...

  8. Pushing Boxes(广度优先搜索)

    题目传送门 首先说明我这个代码和lyd的有点不同:可能更加复杂 既然要求以箱子步数为第一关键字,人的步数为第二关键字,那么我们可以想先找到箱子的最短路径.但单单找到箱子的最短路肯定不行啊,因为有时候不 ...

  9. [poj P1475] Pushing Boxes

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

随机推荐

  1. 前向渲染路径细节 Forward Rendering Path Details

    正向渲染路径细节 Forward Rendering Path Details Forward Rendering path renders each object in one or more pa ...

  2. WWW缓存方式

    缓存方式 使用WWW.LoadFromCacheOrDownload接口.AssetBundles将保存在本地设备的Unity的缓存文件夹中.WebPlayer 有50MB的缓存上限,PC/Mac/A ...

  3. Windows 10 归档、对于一些问题的解决与软件推荐

    I'm a Windows Insider 最近加入了 Windows Insider 计划,主要目的还是为了体验一下马上(7.29)就要发售的 Windows 10 操作系统. 先简要介绍下 Win ...

  4. NSArray & NSDictionary

    一.NSArray 1.1 简单创建方法由难到简 NSArray *arr = [[NSArray alloc] init]; NSArray *arr = [NSArray arrayWithObj ...

  5. Linux ag命令

    一.简介 Ag是用C++写的,搜索速度快,比grep更有效率. 二.安装 RHEL7+ rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x8 ...

  6. [C++] Memory Retrieval(内存检索)

    Traverse the memory by  (char*) , because every time it will increase by 1byte when i want get the i ...

  7. p1429 平面最近点对(加强版)

    传送门 分析 我们可以枚举每一个点算它的最近点 估价函数应该分为3种情况计算: 大于max,小于min,位于min和max之间 代码 #include<iostream> #include ...

  8. redis集群部署及常用的操作命令(下)

    搭建好集群之后,为了扩容需要再加入一个节点.那就再复制一个7006,改为相应的redis.conf(复制了改个port就好,如果复制的redis之前属于集群,需要把关联的node.conf之类的去掉) ...

  9. python 数据清洗

    前言 1. 删除重复 2. 异常值监测 3. 替换 4. 数据映射 5. 数值变量类型化 6. 创建哑变量 统计师的Python日记[第7天:数据清洗(1)] 前言 根据我的Python学习计划: N ...

  10. es-文档版本号,操作类型,分片选择

    一.版本号: 在es中每个文档都有一个版本号,默认情况下,版本号都是随着每次对该文档的修改或者删除自增的,当然你也可以自己指定.有了这个文档号,我们可以像mysql 乐观锁一样,用来进行控制字我们文档 ...