题目链接

http://poj.org/problem?id=1475

题意

推箱子游戏。输入迷宫、箱子的位置、人的位置、目标位置,求人是否能把箱子推到目标位置,若能则输出推的最少的路径,如果有多条步数相同的推的最少的路径,则输出总步数(人走的步数+推箱子的步数)最少的那条路径;若不能把箱子推到目标位置,则输出Impossible.

思路

先求出箱子到目标位置的最短路径(bfs_box),在bfs1推箱子的过程中,根据推的方向和箱子的位置得到人的位置,再求得人到达这个位置的最短路(bfs_person)即可。

代码

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
using namespace std; struct Node
{
int br, bc; //box_row,box_col
int pr, pc; //person_row,person_col
string ans; Node() {}
Node(int br, int bc, int pr, int pc, string ans) :br(br), bc(bc), pr(pr), pc(pc), ans(ans) {}
}; const int N = ;
int m, n;
char maze[N][N];
int dir[][] = { {-, }, {, }, {, -}, {, } };
char push[] = { 'N', 'S', 'W', 'E' };
char walk[] = { 'n', 's', 'w', 'e' };
int br, bc;
int pr, pc;
int tr, tc; bool ok(int r, int c)
{
if (r >= && r < m && c >= && c < n && maze[r][c] != '#')
return true;
return false;
} string tmp;
bool bfs_person(int sr, int sc, int er, int ec, Node node)
{
tmp = "";
int visit[N][N];
memset(visit, , sizeof(visit));
queue<Node> q;
q.push(Node(-, -, sr, sc, ""));
visit[sr][sc] = ;
visit[node.br][node.bc] = ; //注意
while (!q.empty())
{
Node cur = q.front();
q.pop();
if (cur.pr == er && cur.pc == ec)
{
tmp = cur.ans;
return true;
}
for (int i = ; i < ; i++)
{
int nr = cur.pr + dir[i][];
int nc = cur.pc + dir[i][];
if (ok(nr, nc) && !visit[nr][nc])
{
visit[nr][nc] = ;
string ans = cur.ans + walk[i];
q.push(Node(-, -, nr, nc, ans));
}
}
}
return false;
} string bfs_box()
{
int visit[N][N];
memset(visit, , sizeof(visit));
queue<Node> q;
q.push(Node(br, bc, pr, pc, ""));
visit[br][bc] = ;
while (!q.empty())
{
Node cur = q.front();
q.pop();
if (cur.br == tr && cur.bc == tc)
return cur.ans;
for (int i = ; i < ; i++)
{
int nr = cur.br + dir[i][];
int nc = cur.bc + dir[i][];
int pre_r = cur.br - dir[i][];
int pre_c = cur.bc - dir[i][];
if (ok(nr, nc) && ok(pre_r, pre_c) && !visit[nr][nc])
{
if (bfs_person(cur.pr, cur.pc, pre_r, pre_c, cur))
{
visit[nr][nc] = ;
Node next;
next.br = nr;
next.bc = nc;
next.pr = cur.br;
next.pc = cur.bc;
next.ans = cur.ans + tmp + push[i];
q.push(next);
}
}
}
}
return "Impossible.";
} int main()
{
//freopen("poj1475.txt", "r", stdin);
int cnt = ;
while (cin >> m >> n && m)
{
for (int i = ; i < m; i++)
{
for (int j = ; j < n; j++)
{
cin >> maze[i][j];
if (maze[i][j] == 'S')
{
pr = i;
pc = j;
}
else if (maze[i][j] == 'B')
{
br = i;
bc = j;
}
else if (maze[i][j] == 'T')
{
tr = i;
tc = j;
}
}
}
printf("Maze #%d\n", ++cnt);
cout << bfs_box() << endl << endl;
}
return ;
}

poj1475 Pushing Boxes(BFS)的更多相关文章

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

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

  2. POJ1475 Pushing Boxes(双搜索)

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

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

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

  4. hihoCoder 1233 : Boxes(盒子)

    hihoCoder #1233 : Boxes(盒子) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 There is a strange ...

  5. 深搜(DFS)广搜(BFS)详解

    图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...

  6. 【算法导论】图的广度优先搜索遍历(BFS)

    图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...

  7. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

  8. 【BZOJ5492】[HNOI2019]校园旅行(bfs)

    [HNOI2019]校园旅行(bfs) 题面 洛谷 题解 首先考虑暴力做法怎么做. 把所有可行的二元组全部丢进队列里,每次两个点分别向两侧拓展一个同色点,然后更新可行的情况. 这样子的复杂度是\(O( ...

  9. 深度优先搜索(DFS)和广度优先搜索(BFS)

    深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...

随机推荐

  1. VisualSVN 5.1.4破解

    1. 备份visualSVNbin目录 2. 打开VS命令提示工具,反编译VisualSVN.Core.L.dll 运行命令 ildasam "VisualSVN安装目录\bin\Visua ...

  2. Spring整合JMS(四)——事务管理(转)

    *注:别人那复制来的 Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.Jm ...

  3. Dozer 对象的"搬运工"

    前言:项目中,经常会遇到各层对象之间相互进行值传递的过程,如在数据据持久层有一持久类EntityA,在视图层可能会变为ViewA,通常情况下,这两个类的属性 名称 .类型都是一致的,   在两个对象传 ...

  4. 桥接模式_NAT模式_仅主机模式_模型图.ziw

      2017年1月12日, 星期四 桥接模式_NAT模式_仅主机模式_模型图   null

  5. 拦截asp.net输出流做处理

    本文标题是指对已经生成了HTML的页面做一些输出到客户端之前的处理. 方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面 ...

  6. 表格标签(table、行、列、表头)

    表格标签 一.<table> <table>代表表格标签.   <table></table> 1.width  表示表格宽度,宽度表达方式有像素和百分 ...

  7. 面试整理(2)跨域:jsonp与CORS

    问题:跨域有哪些方法?jsonp的原理是什么? jsonp: 先说jsonp,jsonp的主要原理是利用script标签的src可以跨域请求,据说有src属性的都可以跨域请求,但script标签返回的 ...

  8. python初步学习-面向对象之类(一)

    python 面向对象 python 从设计之初就已经是一门面向对象的语言,正因为如此,在python中创建一个类和对象是很容易的. 对象对象奇数简介 类(Class): 用于描述具有相同的属性和方法 ...

  9. python模块之imghdr检测图片类型

    1. imghdr是什么 imghdr是一个用来检测图片类型的模块,传递给它的可以是一个文件对象,也可以是一个字节流. 能够支持的图片格式: 2. 如何使用 提供了一个api叫做imghdr.what ...

  10. bzoj 2741 可持久化trie

    首先我们设si为前i个数的xor和,那么对于询问区间[i,j]的xor和,就相当于si-1^sj,那么对于这道题的询问我们可以处理处si,然后对于询问[l,r],可以表示为在区间[l-1,r]里找两个 ...