一、题面

二、题意分析

一个迷宫中,有一个人Joe和一个或多个起火点,起火点可以蔓延,人可以走动,都只能走4个方向,问人能走出去的最少步数,如果不能输出不可能。很多大佬说是两遍BFS,先一遍火,记录所有火蔓延到次位置的时间,然后再一遍BFS,让Joe去走,只要满足他到该点时,火还未蔓延至此就可以。我一开始就死磕的让火的蔓延与人走同步,但后来发现很多坑!!!后来A了,总结一下,在同步的时候其实需要控制的也是时间,只不过现在的时间是通过控制每次BFS访问的位置的个数来控制的,当Joe在某个时刻可能走的点都访问完后,那么火就蔓延一次,下一次Joe走的时候,要先判断一下,之前入队列的点是否在这一时刻还合法,然后继续访问队列中的其他点,再进行下一层的遍历。最终可得到最终结果。

三、AC代码

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1e3;
int R, C;
bool Maze[MAXN+][MAXN+];
bool visited[MAXN+][MAXN+];
char S[MAXN+];
const int dx[] = {, , , -};
const int dy[] = {, -, , }; struct Point
{
int x, y;
int step;
Point(){};
Point(int a, int b)
{
x = a, y = b;
}
};
queue<Point> FQ;
int BFS(Point J)
{
memset(visited, , sizeof(visited));
queue<Point> JQ;
Point tj , tf, t;
int x, y, Cnt = J.step;
JQ.push(J);
while(!JQ.empty())
{
tj = JQ.front(); if(tj.step > Cnt)
{
Cnt = tj.step;
int L = FQ.size();
for(int i = ; i < L; i++)
{
t = FQ.front();
FQ.pop();
for(int j = ; j < ; j++)
{
x = t.x + dx[j];
y = t.y + dy[j]; if(Maze[x][y] == && x >= && x < R && y >= && y < C)
{ Maze[x][y] = ;
FQ.push(Point(x, y));
}
}
}
}
JQ.pop();
if(Maze[tj.x][tj.y] == )
continue;
for(int i = ; i < ; i++)
{
t.x = tj.x + dx[i];
t.y = tj.y + dy[i];
t.step = tj.step+;
if(t.x < || t.x >= R || t.y < || t.y >= C)
{
return t.step;
}
if(Maze[t.x][t.y] == && visited[t.x][t.y] == )
{
visited[t.x][t.y] = ;
JQ.push(t);
}
}
}
return -;
} int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int T, Ans;
scanf("%d", &T);
int K = ;
while(T--)
{
K++;
memset(Maze, , sizeof(Maze));
while(!FQ.empty())
FQ.pop();
scanf("%d %d", &R, &C);
Point J, F;
for(int i = ; i < R; i++)
{
scanf("%s", S);
for(int j = ; j < C; j++)
{
if(S[j] == '#')
Maze[i][j] = ;
else if(S[j] == '.')
Maze[i][j] = ;
else if(S[j] == 'J')
{
J.x = i, J.y = j;
Maze[i][j] = ;
}
else if(S[j] == 'F')
{
F.x = i, F.y = j;
Maze[i][j] = ;
FQ.push(F);
}
}
}
visited[J.x][J.y] = ;
J.step = ;
Ans = BFS(J);
if(Ans == -)
{
printf("IMPOSSIBLE\n");
}
else
printf("%d\n", Ans);
}
return ;
}

最新文章

  1. 微软消息分析器(Microsoft Message Analyzer )更新至1.2版-2015-1-20
  2. Android Studio导入Vitamio多媒体开发框架
  3. Implicit and Explicit Multithreading MULTITHREADING AND CHIP MULTIPROCESSORS
  4. Java当中的内存分配以及值传递问题内存解析
  5. MiniCrowler
  6. tcpproxy:基于 Swoole 实现的 TCP 数据包转发工具的方法
  7. codeforces 687B - Remainders Game 数学相关(互质中国剩余定理)
  8. Python在Windows下开发环境配置汇总
  9. 使用pypi镜像源加速第三方库在线安装
  10. 安卓4.2原生rom状态栏显示运营商
  11. mapTask并行度优化及源码分析
  12. Android 设计模式实战之关于封装计费代码库的策略模式详谈
  13. C语言极易出错的地方(更新中)
  14. json和pickle模块
  15. Python图像处理之图片文字识别(OCR)
  16. js如何发送wss协议的请求,以及接受服务器返回的数据
  17. 【ES】学习3-请求体查询
  18. Haproxy 重定向跳转设置 - 运维小结
  19. 482. License Key Formatting
  20. SQL Server 2008 允许远程链接 解决方法

热门文章

  1. Yii 2 load() 和 save()
  2. matplotlib的颜色和控制条
  3. 529A And Yet Another Bracket Sequence
  4. sqlServer通过指定的起始时间,创建该时间段内以年、月、日为时间段的临时表
  5. Android onKeyDown、onKeyUp、dispatchKeyEvent的区别
  6. 编写高质量代码改善C#程序的157个建议——建议23:避免将List&lt;T&gt;作为自定义集合类的基类
  7. c# .NET开发邮件发送功能的全面教程(含邮件组件源码)
  8. 策略与计费控制规则(Policy and Charging Control Rule-PCC Rule)解析及模板样例
  9. 状态压缩DP----HDU4049 Tourism Planning
  10. repeater+aspnetpager 组合分页