• kuangbin专题 专题一 简单搜索 Fire! UVA


    题目链接: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 = 1010;
     18 int mv_x[] = { 0, 0, -1, 1 };
     19 int mv_y[] = { 1, -1, 0, 0 };
     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, 1, n) rep(j, 1, m){
     36         Joe[i][j] = 0;
     37         Fire[i][j] = inf;
     38     }
     39 }
     40 
     41 inline void input(){
     42 
     43     l = 0;
     44     rep(i, 1, n) rep(j, 1, 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 >= 1 && x <= n && y >= 1 && y <= m;
     55 }
     56 
     57 void bfs_p(){
     58 
     59     queue<node> que;
     60     Joe[pi][pj] = 1;
     61     que.push(node{ pi, pj, 1 });
     62 
     63     while (!que.empty()){
     64 
     65         node tmp = que.front();
     66         que.pop();
     67         rep__(p, 0, 4){
     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 + 1;
     74                 que.push(node{ dx, dy, tmp.v + 1 });
     75             }
     76         }
     77     }
     78 }
     79 
     80 void bfs_f(int fi, int fj){
     81 
     82     rep(i, 1, n) rep(j, 1, m) vis[i][j] = 0;
     83     queue<node> que;
     84 
     85     Fire[fi][fj] = 1;
     86     vis[fi][fj] = true;
     87     que.push(node{ fi, fj, 1 });
     88 
     89     while (!que.empty()){
     90 
     91         node tmp = que.front();
     92         que.pop();
     93         rep__(p, 0, 4){
     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 + 1 < Fire[dx][dy])  //比较与之前的火源,哪个最先烧到这个点
    102                     Fire[dx][dy] = tmp.v + 1, que.push(node{ dx, dy, tmp.v + 1 });
    103 
    104                 //    cout <<  "Fire[][] " <<  Fire[dx][dy] << endl;
    105 
    106             }
    107         }
    108     }
    109 
    110 
    111 }
    112 
    113 void search_fire(){
    114 
    115     rep__(i, 0, l){
    116         bfs_f(x[i], y[i]);
    117     }
    118 }
    119 
    120 void get_ans(){
    121 
    122     int ans = inf;
    123 
    124     //先把Fire地图所有的inf,也就是无法到达的点赋值为0,方便比较
    125     rep(i, 1, n) rep(j, 1, m) if (Fire[i][j] == inf) Fire[i][j] = 0;
    126 
    127     //一种情况,Joe到达某点时间比Fire短,
    128     //另一个情况,可能Fire到达不了那个点,于是Fire[x][y] == 0,所有有个特殊判断 Fire[x][y] == 0
    129     
    130     //下面就是四个边界情况了
    131     rep(i, 1, n){
    132         if (i == 1 || i == n){
    133             rep(j, 1, m){
    134                 if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == 0 && Joe[i][j] != 0)) 
    135                     ans = min(ans, Joe[i][j]);
    136             }
    137         }
    138         else {
    139             if (Joe[i][1] < Fire[i][1] || (Fire[i][1] == 0 && Joe[i][1] != 0)) 
    140                 ans = min(ans, Joe[i][1]);
    141 
    142             if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == 0 && Joe[i][m] != 0)) 
    143                 ans = min(ans, Joe[i][m]);
    144         }
    145     }
    146 
    147     if (ans == inf) cout << "IMPOSSIBLE" << endl;
    148     else cout << ans << endl;
    149 }
    150 
    151 int main(){
    152 
    153     ios::sync_with_stdio(false);
    154     cin.tie(0);
    155 
    156     int T;
    157     cin >> T;
    158 
    159     rep(i, 1, T){
    160 
    161         cin >> n >> m;
    162         init(); //初始化
    163         input();  //输入
    164         bfs_p();  //Joe的bfs
    165         search_fire();  //所有火源的bfs
    166         get_ans();  //得到答案
    167     }
    168 
    169 
    170     return 0;
    171 }
    1
  • 相关阅读:
    面向对象(OOP:Objdec Oriented Programming)
    vue中v-model和v-bind区别
    DateTimeFormat
    html中frameset简介
    学习及资料地址
    mybatis+oracle批量新增带序列List对象
    Io流读取并输出文件(例如.mp3格式文件)
    Java从服务器下载图片保存到本地
    转:Java DecimalFormat的主要功能及使用方法
    数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11164233.html
Copyright © 2020-2023  润新知