Editorial for Chairs


Approach

Model every coordinate as a graph node with edges to adjacent coordinates inside the classroom. Each move takes one second. The energy cost of an edge is 11 exactly when one endpoint is a chair and the other is ground; otherwise it is 00.

Run a priority queue ordered by (energy, time). For each coordinate, store the smallest time at which it has been reached so far. When a state is popped, ignore it if a faster arrival at the same coordinate has already been found. Otherwise, expand its four neighbours as long as the current time is below tt.

This works because states are processed in nondecreasing energy order. Any lower-energy way to reach a coordinate is expanded before a higher-energy shortcut can make that coordinate's stored time smaller, so discarding arrivals that are not faster cannot remove a better-energy answer. The first time the TA's coordinate is popped, its energy is therefore minimal among all paths that take at most tt seconds.

The time complexity is O(nmlog⁡(nm))O(nm \log(nm)).

Solution (C++)

Code 1
#include <bits/stdc++.h>
using namespace std;

using State = tuple<int, int, int, int>;

const array<pair<int, int>, 4> DIRECTIONS {{
    {0, 1},
    {1, 0},
    {0, -1},
    {-1, 0},
}};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;

    int a, b, c, d, k, t;
    cin >> a >> b >> c >> d >> k >> t;
    --a;
    --b;
    --c;
    --d;

    vector<vector<int>> grid(n, vector<int>(m));
    for (int i = 0; i < k; i++) {
        int x, y;
        cin >> x >> y;
        --x;
        --y;
        grid[x][y] = 1;
    }

    priority_queue<State, vector<State>, greater<State>> pq;
    vector<vector<int>> min_time(n, vector<int>(m, INT_MAX));

    pq.push({0, 0, a, b});
    min_time[a][b] = 0;

    while (!pq.empty()) {
        auto [energy, time, row, col] = pq.top();
        pq.pop();

        if (time != min_time[row][col]) {
            continue;
        }

        if (row == c && col == d) {
            cout << energy << '\n';
            return 0;
        }

        if (time >= t) {
            continue;
        }

        for (auto [dr, dc] : DIRECTIONS) {
            int nr = row + dr;
            int nc = col + dc;

            if (nr < 0 || nr >= n || nc < 0 || nc >= m) {
                continue;
            }

            int next_energy = energy + (grid[row][col] != grid[nr][nc]);
            int next_time = time + 1;

            if (next_time < min_time[nr][nc]) {
                min_time[nr][nc] = next_time;
                pq.push({next_energy, next_time, nr, nc});
            }
        }
    }

    cout << -1 << '\n';
    return 0;
}

Comments0


No comments yet

Be the first to comment.

New comment


Log in to join the discussion.