いむらや競プロ雑記

キーワード:競プロ、育児、石川県

ARC143 A - Three Integers

atcoder.jp

解説にあるような「どれか1つに1を加算する」(その後全部を1引く)操作を読み替えられた場合、上のコードのような感じで解ける。

なお、ABCの値はA[0]A[1]A[2]のリストとし、ソートしてA[0]が大きい前提としている。

A[1]とA[2]にA[0]を合わせるための加算回数をFlatとしているが、その回数だけ全部をマイナスしたいため、最大(結局A[0]なのだが)を超えるとNGとしている。
ここで問題がない場合、Flatにした操作と、Flatにしたことで残る最大の数(Max-Flat)の和なので、結局Maxが答え。

def resolve():

    A = list(map(int, input().split()))

    A.sort(reverse=True)

    Min = min(A)
    Max = max(A)

    Flat = A[0] - A[1] + A[0] - A[2]
    if Flat > Max:
        print(-1)
        return

    ans = Flat + (Max - Flat)
    print(ans)


resolve()

では、その操作の読み替えが思いつかない場合、どうするのがいいだろう。
ということで、以下のような愚直っぽいやり方に逃げるのもありかもしれない。

A[0]が抜きんでている分を、まずはA[1]に合わせたいが、A[0]だけを相対的に下げる操作は、A[0]とA[1]の選択+A[0]とA[2]の選択、の複合なので、それを連打する。
これでも終わらないなら、A[0]とA[1]をA[2]に合わせにいく。
この途中でいずれかの値が負に入ったらNG。そうでない場合は、合わせる操作の合計+A[0](合った後に残った値)が正解。

import math


def resolve():

    A = list(map(int, input().split()))

    A.sort(reverse=True)

    if A[0] == A[1]:
        print(A[0])
        return

    ans = 0
    need = math.ceil((A[0] - A[1]) / 2)
    A[0] -= 2 * need
    A[1] -= need
    A[2] -= need
    ans += need * 2

    if min(A) < 0:
        print(-1)
        return

    if A[2] == 0:
        print(ans + A[0])
        return

    need = A[0] - A[2]
    A[0] -= need
    A[1] -= need
    ans += need

    if min(A) < 0:
        print(-1)
        return

    print(ans + A[0])


resolve()

と、スマートな解にたどり着けなくても、愚直に解けるようになっておいた方がよさそう(どっちも時間内に書けなかった・・・)