Submission #1177554

#TimeUsernameProblemLanguageResultExecution timeMemory
1177554aditya_k47Mecho (IOI09_mecho)C++20
73 / 100
162 ms6240 KiB
#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 timeMemoryGrader output
Fetching results...