IOI 2004
IOI 2004

Hermes

Problem Statement Summary Hermes starts at the origin and must visit N events in order. Event i is at position p_i on axis d_i \ X, Y\. He moves along both axes simultaneously: the time to go from (x_1, y_1) to (x_2,...

Updated May 21, 2026
Track IOI
Year 2004
Statement Not mirrored
TeXC++

Problem Statement

No standalone statement file is available for this entry.

A separate statement file is not available for this entry, so the page focuses on the editorial and implementation.

Editorial

The solution write-up is rendered from the LaTeX source, with equations kept live through MathJax.

Problem Statement Summary

Hermes starts at the origin and must visit $N$ events in order. Event $i$ is at position $p_i$ on axis $d_i \in \{X, Y\}$. He moves along both axes simultaneously: the time to go from $(x_1, y_1)$ to $(x_2, y_2)$ is the Chebyshev distance $\max(|x_2 - x_1|, |y_2 - y_1|)$. Minimize total travel time.

Solution: Interval DP on the Free Axis

Key Observation

After visiting event $i$ (which lies on axis $d_i$), the coordinate on axis $d_i$ is fixed at $p_i$. The coordinate on the other axis is free---Hermes can choose it, subject to the time budget. The optimal strategy tracks an interval of reachable positions on the free axis.

State

After processing event $i$, maintain:

  • $\mathrm{cost}$: total time spent so far (minimum possible).

  • $[\mathrm{lo}, \mathrm{hi}]$: the interval of positions on the free axis that are achievable at cost $\mathrm{cost}$.

Transitions

Same-axis transition

($d_i = d_{i-1}$). The event axis moves from $p_{i-1}$ to $p_i$; this takes at least $\Delta = |p_i - p_{i-1}|$ time. During that time, the free axis can drift by up to $\Delta$ in either direction: \[ \mathrm{cost} \mathrel{+}= \Delta, \qquad \mathrm{lo} \mathrel{-}= \Delta, \qquad \mathrm{hi} \mathrel{+}= \Delta. \]

Cross-axis transition

($d_i \ne d_{i-1}$). The old free axis (now axis $d_i$) had position in $[\mathrm{lo}, \mathrm{hi}]$. We must move it to $p_i$. The minimum extra time is: \[ \delta = \max\bigl(0,\; p_i - \mathrm{hi},\; \mathrm{lo} - p_i\bigr) = \operatorname{dist}(p_i, [\mathrm{lo}, \mathrm{hi}]). \] The new free axis (the old event axis $d_{i-1}$, fixed at $p_{i-1}$) can drift by up to $\delta$ during this extra time: \[ \mathrm{cost} \mathrel{+}= \delta, \qquad \mathrm{lo} = p_{i-1} - \delta, \qquad \mathrm{hi} = p_{i-1} + \delta. \]

Lemma.

The interval representation is exact: every position in $[\mathrm{lo}, \mathrm{hi}]$ is achievable at the stated cost, and no position outside is achievable at lower cost.

Proof.

The Chebyshev distance is the maximum of independent movements on the two axes. Since only one axis is constrained per event, the other axis can freely absorb up to $\mathrm{cost}$ of movement. The interval tracks the exact range of ``slack'' on the free axis.

C++ Implementation

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

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

    int N;
    cin >> N;

    vector<int> d(N), p(N);
    for (int i = 0; i < N; i++) {
        cin >> d[i] >> p[i];
        d[i]--; // 0 = X-axis, 1 = Y-axis
    }

    // Initial move: from (0,0) to event 0 at p[0] on axis d[0].
    // Time = max(|p[0]|, |free|) >= |p[0]|; minimised at |p[0]|.
    // Free axis can be anywhere in [-|p[0]|, |p[0]|].
    long long cost = abs(p[0]);
    long long lo = -abs(p[0]);
    long long hi = abs(p[0]);

    for (int i = 1; i < N; i++) {
        if (d[i] == d[i - 1]) {
            // Same axis: mandatory cost = |p[i] - p[i-1]|
            long long dt = abs(p[i] - p[i - 1]);
            cost += dt;
            lo -= dt;
            hi += dt;
        } else {
            // Cross axis: must reach p[i] from interval [lo, hi]
            long long delta;
            if (p[i] >= lo && p[i] <= hi)
                delta = 0;
            else if (p[i] < lo)
                delta = lo - p[i];
            else
                delta = p[i] - hi;

            cost += delta;
            lo = (long long)p[i - 1] - delta;
            hi = (long long)p[i - 1] + delta;
        }
    }

    cout << cost << "\n";
    return 0;
}

Complexity Analysis

  • Time: $O(N)$---a single pass over the events.

  • Space: $O(N)$ for input storage (the DP uses $O(1)$ extra space).

Code

C++ solution used for this page.

C++

Clean code view with a raw-file link when you want the original source.

Raw file
// IOI 2004 - Hermes
// Visit N events on two axes in order. Cost = Chebyshev distance.
// O(N) interval-tracking DP on the free axis.
#include <bits/stdc++.h>
using namespace std;

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

    int N;
    cin >> N;
    if (N == 0) { cout << 0 << "\n"; return 0; }

    vector<int> d(N), p(N);
    for (int i = 0; i < N; i++) {
        cin >> d[i] >> p[i];
        d[i]--; // 0-indexed: 0 = x-axis, 1 = y-axis
    }

    // Track interval [lo, hi] of reachable free-axis positions at min cost
    long long cost = abs(p[0]);
    long long lo = -abs(p[0]);
    long long hi = abs(p[0]);

    for (int i = 1; i < N; i++) {
        if (d[i] == d[i - 1]) {
            // Same axis: mandatory travel, free axis can drift
            long long dt = abs(p[i] - p[i - 1]);
            cost += dt;
            lo -= dt;
            hi += dt;
        } else {
            // Cross axis: free axis was [lo,hi], must reach p[i] on it
            long long dist;
            if (p[i] >= lo && p[i] <= hi)
                dist = 0;
            else if (p[i] < lo)
                dist = lo - p[i];
            else
                dist = p[i] - hi;

            cost += dist;
            // New free axis centered at p[i-1] with budget dist
            lo = (long long)p[i - 1] - dist;
            hi = (long long)p[i - 1] + dist;
        }
    }

    cout << cost << "\n";
    return 0;
}

Source Files and Assets

Raw files are still available here when you want the original TeX, C++, or statement assets.

Show raw files