Loading [MathJax]/jax/output/CommonHTML/jax.js

目次

ABC 085

AtCoder Beginner Contest 085 - AtCoder

C - Otoshidama

C - Otoshidama

問題

N=1000,Y=1234000 のとき、たとえば10000円札、5000円札、1000円札がそれぞれ14枚、27枚、959枚あれば、合計1000枚で

1000014+500027+1000959=1234000

となり、条件を満たす。また、26枚、0枚、974枚でも条件を満たす。どれを答えてもよい。

解法

O(N^2)

1N2000 なので、全部調べればいける

# 擬似コード

for x in 0 .. N:
    for y in 0 .. N-x:
        if 10000 * x + 5000 * y + 1000 * (N-x-y) == Y:
            # 発見!
            
# ループ終了まで発見できない場合、NとYが不可能な組み合わせである

O(N)

鶴亀算の要領で差分を利用すると、計算量を減らせる

あとは、この x,y を1つずつ調べればよい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def solve(n, y):
    tmp1000 = n * 1000
    if tmp1000 > y:
        return -1, -1, -1
    diff = y - tmp1000
    for y in range(diff // 4000 + 1):
        tmp5000 = y * 4000
        if diff - tmp5000 < 0:
            break
        if (diff - tmp5000) % 9000 == 0:
            x = (diff - tmp5000) // 9000
            if x >= 0 and x + y <= n:
                return x, y, n - x - y
    return -1, -1, -1
 
print(*solve(*map(int, input().split())))

O(1)

連立方程式から考えると、O(1) で解ける。解説放送参照。

Y=Y/1000 として、

x+y+z=N10x+5y+z=Y

ここから、x,y,z が非負整数という条件より、3つの条件式ができる。この条件式を満たす z さえ見つければ、そこから求められる x,y は必ず条件を満たしている。

0zmin(N,Y)Yz5NzYz52(Nz)

一番下は、整理すると以下になる。

5NY4z10NY9

たとえば、N=1000,Y=1234000 なら、

0zmin(1000,1234)=1000z4mod5500012344=941.5z974=1000012349

となり、z=944,949,954,... で解を持つことが分かる。

ただ、計算量的に十分間に合うなら、競技プログラミングでは考察・実装にかかる時間が短い方を選択するべきなので、最初の方法でいい。

D - Katana Thrower

D - Katana Thrower

問題

解法

計算問題だが、考えるべき条件がいくつかある。

とりあえず bi が高い刀から順に投げて、倒せたらそれまでに投げた本数が答え。

投げるだけでは倒せない場合、切ってダメージを与える。投げた後の残りHPを R とすると、ceil(R/amax) で、切る回数が求められる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from math import ceil
 
 
def solve(h, aa, bb):
    max_a = max(aa)
    i = 0
    for b in sorted(bb, reverse=True):
        if b <= max_a:
            break
        i += 1
        h -= b
        if h <= 0:
            return i
    return i + ceil(h / max_a)
 
 
n, h = map(int, input().split())
aa, bb = [], []
for _ in range(n):
    a, b = map(int, input().split())
    aa.append(a)
    bb.append(b)
 
print(solve(h, aa, bb))