题目描述
救救PIPI!!PIPI被关在一个着火的房间里了!
该房间中有 nxm 个位置, 用一个字符矩阵表示。
‘s’ 代表PIPI的起点位置。
‘t’ 代表出口位置。
‘f’ 代表房间的着火点。
‘-’ 代表房间还未着火的点。
房间里面有若干个着火点,每个着火点的移动速率是k , 意思是若一个位置在 x 时刻起火了,那么在 x+k 时刻它周围8个方向都会起火。
PIPI每秒能够移动到上下左右四个方向中的一个未着火的位置。
请你编程计算可怜的PIPI能否成功逃离这个房间,如果PIPI能够成功逃离这个房间,输出PIPI逃出房间的最短时间,如果PIPI不能逃出这个房间,输出"Impossible"。
输入
输入包含多组测试用例。
对于每一组测试用例,输入第一行包含三个整数 n,m,k .分别代表房间位置的行数,列数,以及着火点的移动速率。(1<=n,m,k<=100)
接下来输入一个n*m的字符矩阵,代表房间在0时刻的状态。
以0 0 0 代表输入结束。
输出
对于每组样例,输出一行。如果PIPI能够成功逃离这个房间,输出PIPI逃出房间的最短时间,如果PIPI不能逃出这个房间,输出"Impossible"。
样例输入
样例输出
4
Impossible
Impossible
1
题解代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 120;
const int INF = 1e9;
char g[N][N];
int n, m, k, sx, sy, fx, fy;
int fireTime[N][N];
int st[N][N];
int dx[] = { 0, 1, 0, -1, 1, 1, -1, -1 };
int dy[] = { 1, 0, -1, 0, -1, 1, 1, -1 };
struct Node {
int x, y, t;
};
void countFireTime() {
queue<Node> q;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == 'f') {
fireTime[i][j] = 0;
q.push({ i, j, 0 });
}
else {
fireTime[i][j] = INF; // 这个地方不能初始化为-1
}
if (g[i][j] == 's') {
sx = i, sy = j;
}
if (g[i][j] == 't') {
fx = i, fy = j;
}
}
}
while (q.size()) {
auto now = q.front(); q.pop();
for (int i = 0; i < 8; i++) {
int a = now.x + dx[i], b = now.y + dy[i];
if (a >= 0 && a < n && b >= 0 && b < m && fireTime[a][b] == INF) {
fireTime[a][b] = now.t + k;
q.push({ a, b, now.t + k });
}
}
}
}
void bfs(int x, int y) {
queue<Node> q;
q.push({x, y, 0});
memset(st, -1, sizeof st);
st[x][y] = 0;
while (q.size()) {
auto now = q.front(); q.pop();
if (now.x == fx && now.y == fy) {
cout << now.t << endl;
return;
}
for (int i = 0; i < 4; i++) {
int a = now.x + dx[i], b = now.y + dy[i];
// 如果fireTime初始化为-1,那么这个条件进不去,那么pipi就逃不出去了
if (a >= 0 && a < n && b >= 0 && b < m && st[a][b] == -1 && now.t + 1 < fireTime[a][b]) {
st[a][b] = now.t + 1;
q.push({ a, b, now.t + 1 });
}
}
}
puts("Impossible");
}
int main() {
while (cin >> n >> m >> k && n + m + k > 0) {
for (int i = 0; i < n; i++) cin >> g[i];
countFireTime();
bfs(sx, sy);
}
return 0;
}