题目链接:https://vjudge.net/problem/UVA-11624

题意:一个迷宫,可能有一个或者多个地方着火了,每过1个时间消耗,火会向四周蔓延,问Joe能不能逃出迷宫,只要走出迷宫边界就算逃出,火和Joe都不能透过墙。

思路:人和火源分别跑bfs,人一张地图,火源一张地图,跑各自能到达点的时间,火源可能有多个,
最后只需要判断迷宫的四个边中人和火源的时间消耗来得出最小答案,出不去输出“IMPOSSIBLE”,思路比较简单,代码稍微复杂点。


 #include <iostream>
#include <cstring>
#include<vector>
#include<string>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
using namespace std; #define inf (1LL << 31) - 1
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define rep__(i,j,k) for(int i = (j); i < (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define per__(i,j,k) for(int i = (j); i > (k); i--) const int N = ;
int mv_x[] = { , , -, };
int mv_y[] = { , -, , };
char mp[N][N];
int Fire[N][N]; //火
bool vis[N][N];
int x[N]; //火源的x
int y[N]; //火源的y
int l; //火源的个数
int Joe[N][N]; //Joe
int n, m;
int pi, pj; //Joe的坐标 struct node{
int x, y, v;
}; inline void init(){
rep(i, , n) rep(j, , m){
Joe[i][j] = ;
Fire[i][j] = inf;
}
} inline void input(){ l = ;
rep(i, , n) rep(j, , m){
cin >> mp[i][j]; //记录每个火源
if (mp[i][j] == 'J') pi = i, pj = j;
else if (mp[i][j] == 'F') x[l] = i, y[l++] = j;
}
} inline bool check(int x, int y){
return x >= && x <= n && y >= && y <= m;
} void bfs_p(){ queue<node> que;
Joe[pi][pj] = ;
que.push(node{ pi, pj, }); while (!que.empty()){ node tmp = que.front();
que.pop();
rep__(p, , ){ int dx = tmp.x + mv_x[p];
int dy = tmp.y + mv_y[p]; if (check(dx, dy) && !Joe[dx][dy] && mp[dx][dy] != '#'){
Joe[dx][dy] = tmp.v + ;
que.push(node{ dx, dy, tmp.v + });
}
}
}
} void bfs_f(int fi, int fj){ rep(i, , n) rep(j, , m) vis[i][j] = ;
queue<node> que; Fire[fi][fj] = ;
vis[fi][fj] = true;
que.push(node{ fi, fj, }); while (!que.empty()){ node tmp = que.front();
que.pop();
rep__(p, , ){ int dx = tmp.x + mv_x[p];
int dy = tmp.y + mv_y[p]; if (check(dx, dy) && !vis[dx][dy] && mp[dx][dy] != '#'){
vis[dx][dy] = true; if (tmp.v + < Fire[dx][dy]) //比较与之前的火源,哪个最先烧到这个点
Fire[dx][dy] = tmp.v + , que.push(node{ dx, dy, tmp.v + }); // cout << "Fire[][] " << Fire[dx][dy] << endl; }
}
} } void search_fire(){ rep__(i, , l){
bfs_f(x[i], y[i]);
}
} void get_ans(){ int ans = inf; //先把Fire地图所有的inf,也就是无法到达的点赋值为0,方便比较
rep(i, , n) rep(j, , m) if (Fire[i][j] == inf) Fire[i][j] = ; //一种情况,Joe到达某点时间比Fire短,
//另一个情况,可能Fire到达不了那个点,于是Fire[x][y] == 0,所有有个特殊判断 Fire[x][y] == 0 //下面就是四个边界情况了
rep(i, , n){
if (i == || i == n){
rep(j, , m){
if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == && Joe[i][j] != ))
ans = min(ans, Joe[i][j]);
}
}
else {
if (Joe[i][] < Fire[i][] || (Fire[i][] == && Joe[i][] != ))
ans = min(ans, Joe[i][]); if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == && Joe[i][m] != ))
ans = min(ans, Joe[i][m]);
}
} if (ans == inf) cout << "IMPOSSIBLE" << endl;
else cout << ans << endl;
} int main(){ ios::sync_with_stdio(false);
cin.tie(); int T;
cin >> T; rep(i, , T){ cin >> n >> m;
init(); //初始化
input(); //输入
bfs_p(); //Joe的bfs
search_fire(); //所有火源的bfs
get_ans(); //得到答案
} return ;
}

kuangbin专题 专题一 简单搜索 Fire! UVA - 11624的更多相关文章

  1. E - Fire! UVA - 11624(bfs + 记录火到达某个位置所需要的最小时间)

    E - Fire! UVA - 11624 题目描述 乔在迷宫中工作.不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划.请帮助乔逃离迷宫.根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必 ...

  2. kuangbin专题 专题一 简单搜索 Fire Game FZU - 2150

    题目链接:https://vjudge.net/problem/FZU-2150 题意:’ . '代表火无法烧着的地方,‘ # ’表示草,火可以烧着.选择任意两个‘ # ’(可以两个都选同一个 ‘ # ...

  3. kuangbin专题总结一 简单搜索

    A - 棋盘问题:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有 ...

  4. J - Fire!---UVA 11624

    题目链接 题意:J代表Joe的位置,F代表火的起点,下一刻火将会向四周扩散,求Joe逃离的最短时间,如果不能逃离输出IMPOSSIBLE; 注意火的起点可能不止一处 可以用两次bfs分别求出人到达某个 ...

  5. Fire! UVA - 11624 (两步bfs)

    题目链接 题意 人要从迷宫走出去,火会向四个方向同时扩散 分析 两步bfs,先出火到达各地时的时间(设初始时间为0,人每走一步为1s,在着一步内火可以向四周可触及的方向同时扩散),然后在bfs人,人能 ...

  6. Fire uva 11624

    题目连接:http://acm.hust.edu.cn/vjudge/problem/28833 /* 首先对整个图bfs一次得到火焰燃烧的时刻表 之后在bfs搜路径时加一个火烧表的判断 坑点在于:如 ...

  7. 搜索入门_简单搜索bfs dfs大杂烩

    dfs题大杂烩 棋盘问题  POJ - 1321 和经典的八皇后问题一样.  给你一个棋盘,只有#区域可以放棋子,同时同一行和同一列只能有一个棋子. 问你放k个棋子有多少种方案. 很明显,这是搜索题. ...

  8. [kuangbin带你飞]专题一 简单搜索

            ID Origin Title 454 / 1008 Problem A POJ 1321 棋盘问题   328 / 854 Problem B POJ 2251 Dungeon Ma ...

  9. BFS(两点搜索) UVA 11624 Fire!

    题目传送门 /* BFS:首先对火搜索,求出火蔓延到某点的时间,再对J搜索,如果走到的地方火已经烧到了就不入队,直到走出边界. */ /******************************** ...

随机推荐

  1. 在IOS开发中使用GoogleMaps SDK

    一.申请一个免费的API KEY要使用GoogleMaps SDK,必须要为你的应用申请一个API KEY,API Key可以让你监视你的应用调用api的情况.api key是免费的,你可以在任何调用 ...

  2. boost库asio详解8——几个TCP的简单例子

    摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 void test_asio_synclient() { typedef boost::asio::io_service IoSe ...

  3. 查看 Linux 发行版本的名称以及版本号

    查看LINUX发行版的名称及其版本号的命令: lsb_release -a cat /etc/redhat-release(针对redhat,Fedora)

  4. 微信小程序把玩(三十九)navigation API

    原文:微信小程序把玩(三十九)navigation API 演示效果也看到了小程序也就提供这几个处理导航控制.值得注意的是只能同时导航五个页面 主要属性: 导航条一些方法 wx.setNavigati ...

  5. Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图

    原文:Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图 前面两期学习了 ViewAnimator及其子类ViewSwitcher的使用,以及ViewSwitcher的 ...

  6. c#实现动态加载Dll

    原文:c#实现动态加载Dll 原理如下: 1.利用反射进行动态加载和调用. Assembly assembly=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将 ...

  7. CDC-更改数据捕获存储过程 (Transact-SQL)-学习

    背景: 在SQLServer2008之前,对数据变更的捕获通常使用触发器.时间戳等低效高成本的功能来实现,所以很多系统都没有做数据变更或者仅仅对核心表做监控. 适用环境: 仅在SQLServer200 ...

  8. 预编译加速编译(precompiled_header),指定临时文件生成目录,使项目文件夹更干净(MOC_DIR,RCC_DIR, UI_DIR, OBJECTS_DIR),#pragma execution_character_set("UTF-8")"这个命令是在编译时产生作用的,而不是运行时

    预编译加速编译 QT也可以像VS那样使用预编译头文件来加速编译器的编译速度.首先在.pro文件中加入: CONFIG += precompiled_header 然后定义需要预编译的头文件: PREC ...

  9. notepadd++正则表达式大小写转换

    示例1:将语句 test this sentence 转为大写 查找:^.*$ 替换:\U$0 或------------ 查找:^(.*)$ 替换:\U\1 或 \U$1 示例2:将语句 TEST ...

  10. Impala概念与架构

    Impala概念与架构 下面的内容介绍Cloudera Impala的背景资料及特性,以便你更高效的使用它.Where appropriate, the explanations include co ...