题目链接

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. CSS选择器-常用搜集

    标签选择器: div{ font-size=10px; color=red; background-color=yello; width=200px; height=200px; } <div& ...

  2. Global Vectors forWord Representation

    参考论文: GloVe: Global Vectors forWord Representation 参考博客:https://blog.csdn.net/coderTC/article/detail ...

  3. POJ 3304 Segments 基础线段交判断

    LINK 题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点 思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交.判断 ...

  4. LightOJ1214 Large Division 基础数论+同余定理

    Given two integers, a and b, you should check whether a is divisible by b or not. We know that an in ...

  5. max-device-width和max-width的区别

    比如用媒体查询响应输出@media (max-width: 767px),用谷歌浏览器手机测试插件显示并无变化,其实关键在于max-device-width和max-width,以下摘抄↓ max-d ...

  6. 在eclipse安装mybatis的插件

    1.在help中打开 2.搜索mybatipse 3:功能简介 1:要查找某一个方法        在dao接口中某一个方法中 按住 Ctrl键 鼠标指到方法名称上 选择open xml 就会自动跳转 ...

  7. javaScript 中的一些日常用法总结

    从今天开始把开发中常用到的js语法 一一记录下来 方便以后复习回顾用: 1:对字符串进行替换 replace 以及 replaceAll replace : var begin_date =begin ...

  8. vue--------脚手架vue-cli搭建

    今天在看公司的项目的时候,用到的是Vue框架,哈哈,Vue已经火好久了,想必大家也晓得哈,这里宝宝就不瞎渣渣了~ 由于宝宝已经三个月木有看过代码了,所以对新公司的很多的架构和代码都是懵逼的,再加上宝宝 ...

  9. php中的转义函数

    <?php parse_url 解析URL, 返回各组成部分 urlencode/urldecode url编码/解码 htmlentities 将字符串转化为html实体 htmlentiti ...

  10. hash算法搜索获得api函数地址的实现,"kernel32.dll", "CreateThread"

    我们一般要获得一个函数的地址,通常采用的是明文,例如定义一个api函数字符串"MessageBoxA",然后在GetProcAddress函数中一个字节一个字节进行比较.这样弊端很 ...