diverta 2019 Programming Contest B - RGB Boxes

備忘録

問題

atcoder.jp

回答

import sys, os, math, bisect, itertools, collections, heapq, queue
# from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall
from decimal import Decimal
from collections import defaultdict, deque

sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

MOD = 10 ** 9 + 7
MAX = float('inf')


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    R, G, B, N = il()
    rlimit = (N // R) + 1
    glimit = (N // G) + 1

    ret = 0
    for r in range(rlimit):
        for g in range(glimit):
            n = N - (R * r + G * g)
            if n > -1 and n % B == 0:
                ret += 1
    print(ret)


if __name__ == '__main__':
    main()

考え方

ボールの個数Nが最大3000のため、
愚直に全探索を行なう。


3つの箱に入ったボールの数をR, G, B、選ぶ箱の数をr, g, bとしたとき、
達成すべきボールの個数N個になるためには、
N = R * r + G * g + B * bとなる必要がある。

これをg = (N - (R * r + G * g)) // Bと置き換えることで、
ある一意なrgを決めると、gが存在し得るか否かを判定することが出来る。
gが存在している場合には、ちょうどN個のボールを買うことができるパターンと判定する。

Nの最大は3000程度なので、rgをある一意な値の特定に、
最大でも3000 * 3000回程度のループで行うことが出来る。
あとはこの全てのケースに対してgが存在しえるか否かを判定する。