#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <limits>
using namespace std;
const int INF = 1e9; // large constant for "infinity"
// Directions for movement: down, up, right, left.
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
// Checks if the destination is reachable when waiting `waitTime` minutes before moving.
bool isReachableWithWaitingTime(int waitTime, int n, int s, const vector<string>& grid,
const vector<vector<int>>& dpBees,
pair<int,int> start, pair<int,int> end) {
vector<vector<int>> dp(n, vector<int>(n, INF));
dp[start.first][start.second] = 0;
queue<pair<int,int>> q;
q.push(start);
while (!q.empty()) {
auto [x, y] = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
// Avoid trees ('T') and hives ('H').
if (grid[nx][ny] == 'T' || grid[nx][ny] == 'H') continue;
int newTime = dp[x][y] + 1;
// Multiply by s to avoid floating point division:
// newTime / s < dpBees[nx][ny] - waitTime <=> newTime < s * (dpBees[nx][ny] - waitTime)
if (newTime < dp[nx][ny] && newTime < s * (dpBees[nx][ny] - waitTime)) {
dp[nx][ny] = newTime;
q.push({nx, ny});
}
}
}
}
return dp[end.first][end.second] != INF;
}
// Returns the maximum waiting time that still allows reaching the destination.
int maxWaitingTime(int n, int s, const vector<string>& grid) {
vector<vector<int>> dpBees(n, vector<int>(n, INF));
queue<pair<int,int>> beesQueue;
pair<int,int> start = {-1, -1}, end = {-1, -1};
// Identify bees' positions, start, and destination
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
char cell = grid[i][j];
if (cell == 'H') {
dpBees[i][j] = 0;
beesQueue.push({i, j});
} else if (cell == 'M') {
start = {i, j};
} else if (cell == 'D') {
end = {i, j};
}
}
}
// BFS to compute the time bees take to reach each cell.
while (!beesQueue.empty()) {
auto [x, y] = beesQueue.front();
beesQueue.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
// Bees cannot travel into trees ('T').
if (grid[nx][ny] == 'T') continue;
if (dpBees[nx][ny] > dpBees[x][y] + 1) {
dpBees[nx][ny] = dpBees[x][y] + 1;
beesQueue.push({nx, ny});
}
}
}
}
// Binary search for the maximum waiting time.
int low = 0, high = n * n, ans = -1;
while (low <= high) {
int mid = (low + high) / 2;
if (isReachableWithWaitingTime(mid, n, s, grid, dpBees, start, end)) {
ans = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, s;
cin >> n >> s;
vector<string> grid(n);
for (int i = 0; i < n; i++){
cin >> grid[i];
}
cout << maxWaitingTime(n, s, grid) << "\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |