Official

A - 水の均等化 / Equalizing Water Editorial by admin

GPT 5.2 High

概要

隣り合うタンク間で水を 1 リットルずつ移動できるとき、全タンクの水量を同じにできるかを判定します。結論として「合計水量が \(N\) で割り切れるか」だけを見れば十分です。

考察

まず、この操作では 全体の水量の合計 は絶対に変わりません(減った分が隣へ増えるだけ)。
したがって、最終的に全タンクを同じ水量 \(x\) にするには

  • 合計 \(S=\sum A_i\)\(Nx\) になっている必要がある
  • つまり \(S\)\(N\) で割り切れて \(x=S/N\) が整数である必要がある

これは 必要条件 です。

次にこれが 十分条件(割り切れれば必ずできる)であることを確認します。ポイントは「隣同士にしか動かせない」ことは制約に見えるものの、直線状に連結されているため水は右にも左にも順に運べて、最終的に平均 \(x\) へ調整できるということです。

直感的には、左から順に見ていき、

  • タンク \(i\) が平均 \(x\) より多ければ、その余りを右へ流す
  • 少なければ、右側から必要分を左へ持ってくる(右から左へ 1 リットルずつ移す)

を繰り返せば、最終的に全て \(x\) にできます。
このとき「0 リットルのタンクからは抜けない」制約も問題になりません。左へ運ぶ場合でも、水は右側に存在する分を1リットルずつ隣へ渡していけばよく、途中のタンクが一時的に 0 でも「水がある側から渡す」操作で運搬できます。

具体例: - \(A=[0,3,0],\ N=3,\ S=3,\ x=1\)(割り切れるので可能) - 2番から1番へ1リットル移す → \([1,2,0]\) - 2番から3番へ1リットル移す → \([1,1,1]\)

逆に \(S\)\(N\) で割り切れないと、最終形は必ず整数リットルなので全タンク同量は不可能です。

よって判定は \(S \bmod N == 0\) のみ でよいです。

素朴に「実際に操作をシミュレーションする」方針だと、水量が最大 \(10^9\) なので 1 リットル単位の移動回数が膨大になり、現実的に間に合いません(TLE)。合計の剰余だけを見ることで一瞬で判定できます。

アルゴリズム

  1. 合計水量 \(S=\sum_{i=1}^{N} A_i\) を求める
  2. \(S \bmod N == 0\) なら Yes、そうでなければ No

計算量

  • 時間計算量: \(O(N)\)(合計を計算するだけ)
  • 空間計算量: \(O(1)\)(入力配列を除けば追加領域は定数)

実装のポイント

  • Python では合計が最大で \(10^5 \times 10^9=10^{14}\) になりますが、int は任意精度なのでそのまま扱えます。

  • 入力が大きいので sys.stdin.readline を使うと安全です。

    ソースコード

import sys

def main():
    input = sys.stdin.readline
    N = int(input().strip())
    A = list(map(int, input().split()))
    s = sum(A)
    print("Yes" if s % N == 0 else "No")

if __name__ == "__main__":
    main()

この解説は gpt-5.2-high によって生成されました。

posted:
last update: