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)。合計の剰余だけを見ることで一瞬で判定できます。
アルゴリズム
- 合計水量 \(S=\sum_{i=1}^{N} A_i\) を求める
- \(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: