Sicily 7971. Fire

<span style="font-size: 12pt; line-height: 15pt; font-family: Verdana; background-color: rgb(255, 255, 255);"></span>

7971. Fire

Constraints

Time Limit: 1 secs, Memory Limit: 256 MB

Description

You are trapped in a building consisting of open spaces and walls. Some places are on fire and you have to run for the exit. Will you make it?
At each second, the fire will spread to all open spaces directly connected to the North, South, East or West side of it. Fortunately, walls will never catch fire and will keep the fire inside the building, so as soon as you are out of the building you will be safe. To run to any of the four open spaces adjacent to you takes you exactly one second. You cannot run through a wall or into an open space that is on fire or is just catching fire, but you can run out of an open space at the same moment it catches fire.
Given a map of the building, decide how fast you can exit the building.

Input

On the first line one positive number: the number of test cases, at most 100. After that per test case:

  • one line with two space-separated integers w and h (1 <= w, h <= 1 000): the width and height of the map of the building, respectively.
  • h lines with w characters each: the map of the building, consisting of

– ‘.’: a room,
– ‘#’: a wall,
– ‘@’: your starting location,
– ‘*’: fire.
There will be exactly one ‘@’ in the map.

Output

Per test case:

  • one line with a single integer which is the minimal number of seconds that you need to exit the building or the string “IMPOSSIBLE” when this is not possible.

Sample Input

5
4 3
####
#*@.
####
7 6
###.###
#*#.#*#
#.....#
#.....#
#..@..#
#######
7 4
###.###
#....*#
#@....#
.######
5 5
.....
.***.
.*@*.
.***.
.....
3 3
###
#@#
###

Sample Output

2
5
IMPOSSIBLE
IMPOSSIBLE
IMPOSSIBLE

Problem Source

2013年每周一赛第五场暨校赛模拟赛III/BAPC 2012

// Problem#: 7971
// Submission#: 3593653
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
// Solution to Fire
// Author: Thomas Beuman

// Time complexity: O(w*h)
// Memory: O(w*h)

// @EXPECTED_RESULTS@: CORRECT

// Solution method: BFS

#include <cstdio>
#include <utility>
using namespace std;

typedef pair<int,int> pii;
#define mpii make_pair<int,int>

char Map[1000][1001];
pii BFSqueue[1000000]; // Breadth-first search queue

int main()
{ int cases, casenr, w, h, i, j, i2, j2, d, current, last, distance, scope;
  int di[4] = {0, 0, 1, -1}, dj[4] = {1, -1, 0, 0};
  bool exitfound;
  pii start, loc;
  scanf("%d", &cases);
  for (casenr = 1; casenr <= cases; casenr++)
  { // Read input
    scanf("%d %d", &w, &h);
    for (i = 0; i < h; i++)
      scanf("%s", Map[i]);
    // Put squares with fire on the BFS queue
    last = 0;
    for (i = 0; i < h; i++)
      for (j = 0; j < w; j++)
      { if (Map[i][j] == '*')
          BFSqueue[last++] = mpii(i, j);
        else if (Map[i][j] == '@')
          start = mpii(i, j);
      }
    BFSqueue[last++] = start; // Add the starting position
    // (The starting position goes after the fire, because the fire moves before you do)
    distance = 0; // The distance to all elements in the BFS queue...
    scope = last; // ...up to element #scope
    exitfound = false;
    for (current = 0; !exitfound && current < last; current++)
    { if (current == scope) // Reached the end of the scope:
      { distance++; // Increase the distance
        scope = last; // Reset the scope to the (current) last element
      }
      loc = BFSqueue[current];
      i = loc.first;
      j = loc.second;
      // Try all four directions
      for (d = 0; d < 4; d++)
      { i2 = i + di[d];
        j2 = j + dj[d];
        if (i2 < 0 || i2 >= h || j2 < 0 || j2 >= w) // Out of bounds
        { if (Map[i][j] == '@') // If it's you...
            exitfound = true; // ...you made it!
        }
        else if (Map[i2][j2] == '.') // Unprocessed square
        { Map[i2][j2] = Map[i][j]; // Expand fire / your possible locations
          BFSqueue[last++] = mpii(i2, j2); // Add to BFS queue
        }
      }
    }
    // Output
    if (exitfound)
      printf("%d\n", distance + 1);
    else
      printf("IMPOSSIBLE\n");
  }
  return 0;
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值