Fire! -两次dfs
题目描述:
Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe’s location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it. Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire. Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the fire may enter a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test cases to follow. The first line of each test case contains the two integers R and C, separated by spaces, with 1 ≤ R, C ≤ 1000. The following R lines of the test case each contain one row of the maze. Each of these lines contains exactly C characters, and each of these characters is one of: • #, a wall • ., a passable square • J, Joe’s initial position in the maze, which is a passable square • F, a square that is on fire There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
Sample Output
3
IMPOSSIBLE
题意:Joe要逃离一个迷宫,迷宫中有地方起火了,在火开始燃烧的时候Joe也开始逃,火的蔓延方式与Joe的行动方式一样,都是1个单位时间可以往上下左右四个方向各走一格。另外,迷宫内有墙,Joe与火都无法穿墙。现在给你一个图,请问Joe能否从迷宫的边界处逃出而不被火烧到,如果能的话请输出最短的逃脱时间,不能的话输出“IMPOSSIBLE”。其中,‘F’代表火,‘J’代表Joe,‘#’代表墙。
解题思路:参考博客 https://blog.csdn.net/JZQT_T/article/details/38641127
这题首先注意的就是,起火点可能不止一个,也可能没有起火点。其次是如果一个起火点被四周的墙给封闭起来了,那么这个火就相当于没有用了。为了判断Joe走到某个点时这个点是否已经起火,我们需要知道每个点起火的时间。其实可以把每个初始起火点当成一个起火点的邻节点加入队列,这样就只进行了一次BFS,从而获得了每个点起火的时间(如果有些点不会起火,那么这些点的时间就是初始化的INF)。最后从Joe的起点开始BFS一次,如果走到下一个点时那个点已经或者刚好着火了那就不能走,墙也不能走,只要走到边界就说明可以走出迷宫了。
代码:
//直接预处理出火烧到每一个格子的时间,bfsbfs的时候,已经有火在烧的格子和墙一样处理就行了,火烧时间的预处理也用bfsbfs就行
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std; #define N 1001
#define INF 999999999 struct point //定义点结构体
{
int x, y; //坐标
int step; //步数,相当于时间
}; int dx[] = {, -, , }; //方向向量
int dy[] = {, , -, }; //方向向量 int n, m, t;
char map[N][N];
int vis[N][N]; //记录火或者人到达点花费的最少时间
point start, fire; //起点和起火处
queue <point> q; void FireBfs()
{
point a, b;
while (!q.empty())
{
a = q.front();
q.pop();
for (int j=; j<; ++j)
{
int nx = a.x + dx[j];
int ny = a.y + dy[j];
if (nx < || nx >= n || ny < || ny >= m) continue; //越界
if (map[nx][ny] == '#' || vis[nx][ny] <= a.step + ) continue; //墙或者已经走过的点
b.x = nx;
b.y = ny;
//走到这一格的时间=火烧到这一格的时间=上一格的步数加1
b.step = vis[nx][ny] = a.step + ;
q.push(b);
}
}
return;
} void DataProcess()
{
point a, b;
FireBfs();
q.push(start); //将人的起点加入队列准备Bfs
while (!q.empty())
{
a = q.front();
q.pop();
for (int i=; i<; ++i)
{
int nx = a.x + dx[i];
int ny = a.y + dy[i];
if (nx < || nx >= n || ny < || ny >= m) //成功走到边界
{
printf("%d\n", a.step + );
return;
}
if (map[nx][ny] == '#' || vis[nx][ny] <= a.step + ) continue; //遇到墙或者该点起火或者走过
b.x = nx;
b.y = ny;
b.step = vis[nx][ny] = a.step + ;//走到这一步的时间=火烧到这一格的时间=上一格的步数加1
q.push(b);
}
}
puts("IMPOSSIBLE");
return;
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d %d", &n, &m);
for (int i=; i<n; ++i)
{
scanf("%s", map[i]);
}
while (!q.empty()) q.pop(); //清空队列
for (int i=; i<n; ++i)
{
for (int j=; j<m; ++j)
{
vis[i][j] = INF; //初始vis
if (map[i][j] == 'J')
{
start.x = i;
start.y = j;
start.step = ;
vis[i][j] = ;
}
else if (map[i][j] == 'F')
{
fire.x = i;
fire.y = j;
fire.step = ;
q.push(fire); //加入队列准备进行火的Bfs
vis[i][j] = ;
}
}
}
DataProcess();
}
return ;
}
Fire! -两次dfs的更多相关文章
- HDU 4607 Park Visit 两次DFS求树直径
两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R: ans = ...
- 蒟蒻浅谈树链剖分之一——两个dfs操作
树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作 首先我们需要明白在树链剖分中的一些概念 重儿子:某节点所有儿子中子树最多的儿子 重链:有重儿子构成的链 dfs序:按重儿子优先遍历时 ...
- 蓝桥杯 大臣的旅费_树的最长度_两次DFS
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> ...
- 【2-SAT(两次DFS版)】BZOJ1823-[JSOI2010]满汉全席
[题目大意] 有n个材料,m个评委.每种材料可以被用来做满族菜或汉族菜,m个评委有两种可以让他满意的猜中.问是否可以满足所有评委要求? [思路] 每天只能做三道题,我已经是一个废人了……(葛优躺.jp ...
- 两次DFS,POJ(1481)
题目链接:http://poj.org/problem?id=1481 两次DFS,这里的思路是,没找到*,就说明,有一个骰子,因此,每搜索到一个*,深搜4个方向,并且变为'.',要是搜到'X',就是 ...
- 黑科技——树剖两次dfs转一次dfs!
黑科技--树剖两次\(dfs\)转一次\(dfs\)! 重所周知,树链剖分通常是要\(dfs\)两次的,就像这样: int Fa[N],dep[N],Sz[N],son[N]; void dfs1( ...
- ZOJ 1002:Fire Net(DFS+回溯)
Fire Net Time Limit: 2 Seconds Memory Limit: 65536 KB Suppose that we have a square city with s ...
- HDU1045 Fire Net(DFS枚举||二分图匹配) 2016-07-24 13:23 99人阅读 评论(0) 收藏
Fire Net Problem Description Suppose that we have a square city with straight streets. A map of a ci ...
- HDU 1045 Fire Net(DFS 与8皇后问题类似)
Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- 洛谷P5110 块速递推 [分块]
传送门 思路 显然可以特征根方程搞一波(生成函数太累),得到结果: \[ a_n=\frac 1 {13\sqrt{337}} [(\frac{233+13\sqrt{337}}{2})^n-(\fr ...
- 一篇文章让你了解Android各个版本的历程
2008年--至今 Android 1.5(Cupcake纸杯蛋糕): 智能虚拟键盘:使用widgets实现桌面个性化:在线文件夹(Live Folder)快速浏览在线数据:视频录制和分享:图片上传: ...
- swift 学习- 19 -- 可选链式调用
// 可选链式调用 是一种在当前值可能为 nil 的可选值上请求 和 调用属性, 方法以及下标, 如果 可选值有值, 那么调用就会成功, 如果可选值是 nil, 那么就会将返回 nil , // 多个 ...
- Modbus库开发笔记之三:Modbus TCP Server开发
在完成了前面的工作后,我们就可以实现有针对性的应用了,首先我们来实现Modbus TCP的服务器端应用.当然我们不是做具体的应用,而是对Modbus TCP的服务器端应用进行封装以供有需要时调用. 这 ...
- Confluence 6 查看一个任务的执行历史
希望查看一个计划任务最后运行的时间和这个计划任务最后一次运行花费了多长时间.单击计划任务边上的 历史(History )连接. 如果一个计划任务从来没有运行的胡啊,那么这个历史的链接是不会显示的. 屏 ...
- vue阿里上传图片报400错误
首先我用vue上传阿里图片用的是分片上传,分片上传由于一片是以100kb为起始的,所以当图片大小小于100kb的时候不分片,可以正常上传,当大于100kb的时候,会报400错误如下 One or mo ...
- python之vscode中手动选择python解释器(mac)
要选择特定的解释器,请从命令选项板(⇧⌘P)调用Python:Select Interpreter命令. 更详细请看:http://www.cnblogs.com/it-tsz/p/9312151.h ...
- Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器)
Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器) 1.初始函数 2.函数嵌套及作用域 3.装饰器 4.迭代器和生成器 6.内置函数 7.递归函数 8.匿名函数
- Matplotlib模块:绘图和可视化
一.简单介绍Matplotlib 1.Matplotlib是一个强大的Python绘图和数据可视化的工具包 2.安装方法:pip install matplotlib 3.引用方法:import ma ...
- java常见错误总结
1. 现象:将数组转为List后进行removeAll()操作,报java.lang.UnsupportedOperationException错误. 代码: /** * 获取标记ID * @retu ...