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

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

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


  1. #include <iostream>
  2. #include <cstring>
  3. #include<vector>
  4. #include<string>
  5. #include <cmath>
  6. #include <map>
  7. #include <queue>
  8. #include <algorithm>
  9. using namespace std;
  10.  
  11. #define inf (1LL << 31) - 1
  12. #define rep(i,j,k) for(int i = (j); i <= (k); i++)
  13. #define rep__(i,j,k) for(int i = (j); i < (k); i++)
  14. #define per(i,j,k) for(int i = (j); i >= (k); i--)
  15. #define per__(i,j,k) for(int i = (j); i > (k); i--)
  16.  
  17. const int N = ;
  18. int mv_x[] = { , , -, };
  19. int mv_y[] = { , -, , };
  20. char mp[N][N];
  21. int Fire[N][N]; //火
  22. bool vis[N][N];
  23. int x[N]; //火源的x
  24. int y[N]; //火源的y
  25. int l; //火源的个数
  26. int Joe[N][N]; //Joe
  27. int n, m;
  28. int pi, pj; //Joe的坐标
  29.  
  30. struct node{
  31. int x, y, v;
  32. };
  33.  
  34. inline void init(){
  35. rep(i, , n) rep(j, , m){
  36. Joe[i][j] = ;
  37. Fire[i][j] = inf;
  38. }
  39. }
  40.  
  41. inline void input(){
  42.  
  43. l = ;
  44. rep(i, , n) rep(j, , m){
  45. cin >> mp[i][j];
  46.  
  47. //记录每个火源
  48. if (mp[i][j] == 'J') pi = i, pj = j;
  49. else if (mp[i][j] == 'F') x[l] = i, y[l++] = j;
  50. }
  51. }
  52.  
  53. inline bool check(int x, int y){
  54. return x >= && x <= n && y >= && y <= m;
  55. }
  56.  
  57. void bfs_p(){
  58.  
  59. queue<node> que;
  60. Joe[pi][pj] = ;
  61. que.push(node{ pi, pj, });
  62.  
  63. while (!que.empty()){
  64.  
  65. node tmp = que.front();
  66. que.pop();
  67. rep__(p, , ){
  68.  
  69. int dx = tmp.x + mv_x[p];
  70. int dy = tmp.y + mv_y[p];
  71.  
  72. if (check(dx, dy) && !Joe[dx][dy] && mp[dx][dy] != '#'){
  73. Joe[dx][dy] = tmp.v + ;
  74. que.push(node{ dx, dy, tmp.v + });
  75. }
  76. }
  77. }
  78. }
  79.  
  80. void bfs_f(int fi, int fj){
  81.  
  82. rep(i, , n) rep(j, , m) vis[i][j] = ;
  83. queue<node> que;
  84.  
  85. Fire[fi][fj] = ;
  86. vis[fi][fj] = true;
  87. que.push(node{ fi, fj, });
  88.  
  89. while (!que.empty()){
  90.  
  91. node tmp = que.front();
  92. que.pop();
  93. rep__(p, , ){
  94.  
  95. int dx = tmp.x + mv_x[p];
  96. int dy = tmp.y + mv_y[p];
  97.  
  98. if (check(dx, dy) && !vis[dx][dy] && mp[dx][dy] != '#'){
  99. vis[dx][dy] = true;
  100.  
  101. if (tmp.v + < Fire[dx][dy]) //比较与之前的火源,哪个最先烧到这个点
  102. Fire[dx][dy] = tmp.v + , que.push(node{ dx, dy, tmp.v + });
  103.  
  104. // cout << "Fire[][] " << Fire[dx][dy] << endl;
  105.  
  106. }
  107. }
  108. }
  109.  
  110. }
  111.  
  112. void search_fire(){
  113.  
  114. rep__(i, , l){
  115. bfs_f(x[i], y[i]);
  116. }
  117. }
  118.  
  119. void get_ans(){
  120.  
  121. int ans = inf;
  122.  
  123. //先把Fire地图所有的inf,也就是无法到达的点赋值为0,方便比较
  124. rep(i, , n) rep(j, , m) if (Fire[i][j] == inf) Fire[i][j] = ;
  125.  
  126. //一种情况,Joe到达某点时间比Fire短,
  127. //另一个情况,可能Fire到达不了那个点,于是Fire[x][y] == 0,所有有个特殊判断 Fire[x][y] == 0
  128.  
  129. //下面就是四个边界情况了
  130. rep(i, , n){
  131. if (i == || i == n){
  132. rep(j, , m){
  133. if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == && Joe[i][j] != ))
  134. ans = min(ans, Joe[i][j]);
  135. }
  136. }
  137. else {
  138. if (Joe[i][] < Fire[i][] || (Fire[i][] == && Joe[i][] != ))
  139. ans = min(ans, Joe[i][]);
  140.  
  141. if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == && Joe[i][m] != ))
  142. ans = min(ans, Joe[i][m]);
  143. }
  144. }
  145.  
  146. if (ans == inf) cout << "IMPOSSIBLE" << endl;
  147. else cout << ans << endl;
  148. }
  149.  
  150. int main(){
  151.  
  152. ios::sync_with_stdio(false);
  153. cin.tie();
  154.  
  155. int T;
  156. cin >> T;
  157.  
  158. rep(i, , T){
  159.  
  160. cin >> n >> m;
  161. init(); //初始化
  162. input(); //输入
  163. bfs_p(); //Joe的bfs
  164. search_fire(); //所有火源的bfs
  165. get_ans(); //得到答案
  166. }
  167.  
  168. return ;
  169. }

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. IdentityServer学习目录

    IdentityServer IdentityServer的基本概念与特性 IdentityServer流程图与相关术语 最简单的IdentityServer实现 最简单的IdentityServer ...

  2. c#通过datatable导出excel和word

    /// <summary> /// 导出datatable到word /// </summary> /// <param name="dg">需 ...

  3. 【Android】解决微信调起支付接口没反应,调不起来微信的问题

    原文:[Android]解决微信调起支付接口没反应,调不起来微信的问题 //#前言 吐槽一下,微信支付的sdk真难用,文档混乱,坑不少. 正文:可能引起这种情况的问题 1. 最不能出现的 你的APPI ...

  4. 使用path制作各类型动画路径

    原文:使用path制作各类型动画路径 <Window x:Class="使用path制作各类型动画路径.MainWindow" xmlns="http://sche ...

  5. 专门用于消息回调窗口的窗口标识HWND_MESSAGE(创建一个非可视、没有z-order的窗口)

    HWND_MESSAGE Message-Only Windows A message-only window enables you to send and receive messages. It ...

  6. C# Lambda表达式Contains方法 like

    原文:Lambda表达式Contains方法 like 1.使用Contains方法的必备条件: Contains等价于SQL中的like语句.不过Contains只针对于字符串(string)类型的 ...

  7. 零元学Expression Blend 4 - Chapter 40 Flash做的到的Blend也可以!轻松制作拥有动画的MenuBar!(上)

    原文:零元学Expression Blend 4 - Chapter 40 Flash做的到的Blend也可以!轻松制作拥有动画的MenuBar!(上) 一直以来都有人拿Flash的动画问我Blend ...

  8. SignalR---DOTNET客户端

    原文:SignalR---DOTNET客户端 这里面有用到异步的相关知识,本人前几篇文章也简单的提到. SignalR客户端要寄宿在.NET的客户端,必须安装Microsoft.AspNet.Sign ...

  9. The Portable Executable File Format from Top to Bottom(每个结构体都非常清楚)

    The Portable Executable File Format from Top to Bottom Randy KathMicrosoft Developer Network Technol ...

  10. Hadoop 3、Hadoop 分布式存储系统 HDFS(好多彩色图)

    HDFS是Hadoop Distribute File System 的简称,也就是Hadoop的一个分布式文件系统. 一.HDFS的优缺点 1.HDFS优点: a.高容错性 .数据保存多个副本 .数 ...