Official

A - Jogging Editorial by KoD


高橋君は \(A+C\) 秒の周期で同じ行動を繰り返します。具体的には、\(k\) を非負整数として、高橋君が出発して \(k\) 秒後から \(k+1\) 秒後にかけての行動は

  • \(k\)\(A+C\) で割った余りが \(A\) より小さいとき、\(B\) メートル歩く
  • そうでない場合、動かない

となります。同様に、青木君の行動は

  • \(k\)\(D+F\) で割った余りが \(D\) より小さいとき、\(E\) メートル歩く
  • そうでない場合、動かない

\(k = 0, 1, \dots, X - 1\) について上記の判定を行うことで、二人がそれぞれ何メートル進んだか計算することができます。よって、この問題を \(O(X)\) の時間計算量で解くことができました。

実装例 (C++) :

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

int main() {
    int a, b, c, d, e, f, x;
    cin >> a >> b >> c >> d >> e >> f >> x;
    int takahashi = 0, aoki = 0;
    for (int k = 0; k < x; ++k) {
        if (k % (a + c) < a) {
            takahashi += b;
        }
        if (k % (d + f) < d) {
            aoki += e;
        }
    }
    if (takahashi > aoki) {
        cout << "Takahashi\n";
    } else if (takahashi < aoki) {
        cout << "Aoki\n";
    } else {
        cout << "Draw\n";
    }
    return 0;
}

なお、より高速に(\(O(1)\) の時間計算量で)解くこともできます。

高橋君の行動を \(A + C\) 秒間隔で区切り、これを \(1\) 周期とします。高橋君は \(1\) 周期あたり \(A \times B\) メートル進み、ある周期のはじめの \(k\) 秒(\(0 \leq k \leq A + C\))で \(\min(A, k) \times B\) メートル進むことがわかります。

高橋君が出発してから \(X\) 秒間でちょうど \(q\) 周期を完全に終えるとすると \(q =\left\lfloor \frac{X}{A + C} \right\rfloor\) です。残った \(X - (A + C) \times q\) 秒間はある同一の周期に属するので、高橋君が \(X\) 秒間に進む距離の合計は \(A \times B \times q + \min(A, X - (A + C) \times q) \times B\) メートルとなります。

青木君についても同様であるので、二人がそれぞれ進んだ距離を定数時間で計算することができます。

実装例 (Python) :

def solve(a, b, c, x):
  q = x // (a + c)
  r = x % (a + c);
  return (q * a + min(a, r)) * b;

a, b, c, d, e, f, x = map(int, input().split())

takahashi = solve(a, b, c, x)
aoki = solve(d, e, f, x)

if takahashi > aoki:
  print("Takahashi")
elif takahashi < aoki:
  print("Aoki")
else:
  print("Draw")

posted:
last update: