-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
escape-the-spreading-fire.cpp
122 lines (119 loc) · 5.29 KB
/
escape-the-spreading-fire.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Time: O(m * n)
// Space: O(m * n)
// bfs
class Solution {
public:
int maximumMinutes(vector<vector<int>>& grid) {
static const vector<pair<int, int>> directions{{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
enum State {GRASS, FIRE, WALL, PERSON};
const int INF = 1e9;
const auto& bfs = [&]() {
unordered_map<int, unordered_map<int, unordered_map<int, int>>> time;
vector<tuple<int, int, int>> q;
for (int r = 0; r < size(grid); ++r) {
for (int c = 0; c < size(grid[0]); ++c) {
if (grid[r][c] == FIRE) {
q.emplace_back(r, c, FIRE);
}
}
}
q.emplace_back(0, 0, PERSON);
for (int d = 0; !empty(q); ++d) {
vector<tuple<int, int, int>> new_q;
for (const auto& [r, c, t] : q) {
for (const auto& [dr, dc] : directions) {
const int nr = r + dr, nc = c + dc;
if (!(0 <= nr && nr < size(grid) && 0 <= nc && nc < size(grid[0]) &&
grid[nr][nc] != WALL &&
((t == FIRE && grid[nr][nc] != FIRE) ||
(t == PERSON && (grid[nr][nc] == GRASS ||
(grid[nr][nc] == FIRE && nr == size(grid) - 1 && nc == size(grid[0]) - 1 && d + 1 == time[FIRE][nr][nc])))))) {
continue;
}
if (grid[nr][nc] != FIRE) {
grid[nr][nc] = t;
}
if ((nr == size(grid) - 1 && nc == size(grid[0]) - 1) ||
(nr == size(grid) - 1 && nc == size(grid[0]) - 2) ||
(nr == size(grid) - 2 && nc == size(grid[0]) - 1)) {
time[t][nr][nc] = d + 1;
}
new_q.emplace_back(nr, nc, t);
}
}
q = move(new_q);
}
return time;
};
auto time = bfs();
if (!time[PERSON][size(grid) - 1][size(grid[0]) - 1]) {
return -1;
}
if (!time[FIRE][size(grid) - 1][size(grid[0]) - 1]) {
return INF;
}
const int diff = time[FIRE][size(grid) - 1][size(grid[0]) - 1] - time[PERSON][size(grid) - 1][size(grid[0]) - 1];
return (time[FIRE][size(grid) - 1][size(grid[0]) - 2] - time[PERSON][size(grid) - 1][size(grid[0]) - 2] == diff + 2 ||
time[FIRE][size(grid) - 2][size(grid[0]) - 1] - time[PERSON][size(grid) - 2][size(grid[0]) - 1] == diff + 2)
? diff
: diff - 1;
}
};
// Time: O(m * n)
// Space: O(m * n)
// bfs
class Solution2 {
public:
int maximumMinutes(vector<vector<int>>& grid) {
static const vector<pair<int, int>> directions{{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
enum State {FIRE = 1, WALL, PERSON};
const int INF = 1e9;
const auto& bfs = [&]() {
unordered_map<int, vector<vector<int>>> time;
time[FIRE] = vector<vector<int>>(size(grid), vector<int>(size(grid[0]), INF));
time[PERSON] = vector<vector<int>>(size(grid), vector<int>(size(grid[0]), INF));
vector<tuple<int, int, int>> q;
for (int r = 0; r < size(grid); ++r) {
for (int c = 0; c < size(grid[0]); ++c) {
if (grid[r][c] == FIRE) {
q.emplace_back(r, c, FIRE);
}
}
}
q.emplace_back(0, 0, PERSON);
for (const auto& [r, c, t] : q) {
time[t][r][c] = 0;
}
for (int d = 0; !empty(q); ++d) {
vector<tuple<int, int, int>> new_q;
for (const auto& [r, c, t] : q) {
for (const auto& [dr, dc] : directions) {
const int nr = r + dr, nc = c + dc;
if (!(0 <= nr && nr < size(grid) && 0 <= nc && nc < size(grid[0]) &&
grid[nr][nc] != WALL && time[t][nr][nc] == INF &&
(t == FIRE ||
d + 1 < time[FIRE][nr][nc] || (d + 1 == time[FIRE][nr][nc] && nr == size(grid) - 1 && nc == size(grid[0]) - 1)))) {
continue;
}
time[t][nr][nc] = d + 1;
new_q.emplace_back(nr, nc, t);
}
}
q = move(new_q);
}
return time;
};
auto time = bfs();
if (time[PERSON][size(grid) - 1][size(grid[0]) - 1] == INF) {
return -1;
}
if (time[FIRE][size(grid) - 1][size(grid[0]) - 1] == INF) {
return INF;
}
const int diff = time[FIRE][size(grid) - 1][size(grid[0]) - 1] - time[PERSON][size(grid) - 1][size(grid[0]) - 1];
return (time[FIRE][size(grid) - 1][size(grid[0]) - 2] - time[PERSON][size(grid) - 1][size(grid[0]) - 2] == diff + 2 ||
time[FIRE][size(grid) - 2][size(grid[0]) - 1] - time[PERSON][size(grid) - 2][size(grid[0]) - 1] == diff + 2)
? diff
: diff - 1;
}
};