POJ1475 Pushing Boxes(双搜索)
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(双搜索)的更多相关文章
- poj1475 Pushing Boxes[双重BFS(毒瘤搜索题)]
地址. 很重要的搜索题.★★★ 吐槽:算是写过的一道码量比较大的搜索题了,细节多,还比较毒瘤.虽然是一遍AC的,其实我提前偷了大数据,但是思路还是想了好长时间,照理说想了半小时出不来,我就会翻题解,但 ...
- POJ1475(Pushing Boxes)--bbffss
题目在这里 题目一看完就忙着回忆童年了.推箱子的游戏. 假设只有一个箱子.游戏在一个R行C列的由单位格子组成的区域中进行,每一步, 你可以移动到相邻的四个格子中的一个,前提是那个格子是空的:或者,如果 ...
- poj1475 -- Pushing Boxes
这道题其实挺有趣 的,这让我想起小时候诺基亚手机上的推箱子游戏(虽然一点也不好玩) (英文不好-->) 题意翻译: 初始人(S),箱子(B),目的地(T)用人把箱子推到 T最小步数及其路径(满 ...
- POJ-1475 Pushing Boxes (BFS+优先队列)
Description Imagine you are standing inside a two-dimensional maze composed of square cells which ma ...
- poj1475 Pushing Boxes(BFS)
题目链接 http://poj.org/problem?id=1475 题意 推箱子游戏.输入迷宫.箱子的位置.人的位置.目标位置,求人是否能把箱子推到目标位置,若能则输出推的最少的路径,如果有多条步 ...
- POJ1475 Pushing Boxes(BFS套BFS)
描述 Imagine you are standing inside a two-dimensional maze composed of square cells which may or may ...
- POJ1475 Pushing Boxes 华丽丽的双重BFS
woc累死了写了两个半小时...就是BFS?我太菜了... 刚开始以为让人预先跑一遍BFS,然后一会儿取两节加起来就好了,结果发现求出来的最短路(就是这个意思)会因箱子的移动而变化....我死了QWQ ...
- Pushing Boxes(广度优先搜索)
题目传送门 首先说明我这个代码和lyd的有点不同:可能更加复杂 既然要求以箱子步数为第一关键字,人的步数为第二关键字,那么我们可以想先找到箱子的最短路径.但单单找到箱子的最短路肯定不行啊,因为有时候不 ...
- [poj P1475] Pushing Boxes
[poj P1475] Pushing Boxes Time Limit: 2000MS Memory Limit: 131072K Special Judge Description Ima ...
随机推荐
- 前向渲染路径细节 Forward Rendering Path Details
正向渲染路径细节 Forward Rendering Path Details Forward Rendering path renders each object in one or more pa ...
- WWW缓存方式
缓存方式 使用WWW.LoadFromCacheOrDownload接口.AssetBundles将保存在本地设备的Unity的缓存文件夹中.WebPlayer 有50MB的缓存上限,PC/Mac/A ...
- Windows 10 归档、对于一些问题的解决与软件推荐
I'm a Windows Insider 最近加入了 Windows Insider 计划,主要目的还是为了体验一下马上(7.29)就要发售的 Windows 10 操作系统. 先简要介绍下 Win ...
- NSArray & NSDictionary
一.NSArray 1.1 简单创建方法由难到简 NSArray *arr = [[NSArray alloc] init]; NSArray *arr = [NSArray arrayWithObj ...
- Linux ag命令
一.简介 Ag是用C++写的,搜索速度快,比grep更有效率. 二.安装 RHEL7+ rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x8 ...
- [C++] Memory Retrieval(内存检索)
Traverse the memory by (char*) , because every time it will increase by 1byte when i want get the i ...
- p1429 平面最近点对(加强版)
传送门 分析 我们可以枚举每一个点算它的最近点 估价函数应该分为3种情况计算: 大于max,小于min,位于min和max之间 代码 #include<iostream> #include ...
- redis集群部署及常用的操作命令(下)
搭建好集群之后,为了扩容需要再加入一个节点.那就再复制一个7006,改为相应的redis.conf(复制了改个port就好,如果复制的redis之前属于集群,需要把关联的node.conf之类的去掉) ...
- python 数据清洗
前言 1. 删除重复 2. 异常值监测 3. 替换 4. 数据映射 5. 数值变量类型化 6. 创建哑变量 统计师的Python日记[第7天:数据清洗(1)] 前言 根据我的Python学习计划: N ...
- es-文档版本号,操作类型,分片选择
一.版本号: 在es中每个文档都有一个版本号,默认情况下,版本号都是随着每次对该文档的修改或者删除自增的,当然你也可以自己指定.有了这个文档号,我们可以像mysql 乐观锁一样,用来进行控制字我们文档 ...