1
1

More than 3 years have passed since last update.

【AtCoder】ABC210をPython3で解説

Last updated at Posted at 2021-07-19

ABC210の解説。

A - Cabbages

解説

キャベツ1つ$x$円。
もし、キャベツを$A$個より多く買うとき、次から買うキャベツは$Y$円で買うことができる。

キャベツを$N$個買うとき、必要な金額はいくらかという問題。

問題文の通り実装すれば、ACできる。注意点は、もし$A$よりも多いとき、というところだ。

コード

n, a, x, y = map(int, input().split())

if n > a:
    print(x*a+(n-a)*y)
else:
    print(x*n)

B - Bouzu Mekuri

解説

問題の解釈をすると、文字列$S$のなかで先に$1$を出したほうの名前を出力するという問題。

文字列$S$を1文字ずつ確認していって、$1$が出たときに条件分岐。偶数番目なら、青木くんの負けなのでprint('Aoki')、奇数番目なら、高橋くんの負けなのでprint('Takahashi')を出力します。

コード

n = int(input())
slist = list(input())
cnt = 0

for s in slist:
    cnt += 1
    if s == '1':
        if cnt % 2 != 0:
            print('Takahashi')
        else:
            print('Aoki')
        break

C - Colorful Candies

解説

$N$個のキャンディーがそれぞれ$c$色になっている。連続した$K$個のキャンディーからとれる最大の色の種類数を取るという問題。

今回の注意点は、$K$と$N$の最大値が$3 \times 10^5$であるということ。つまり、計算量が$O(n^2)$となると、TLEしてしまう。したがって、これより少ない計算量で解かなければならない。

コードにおいて工夫した点は、dequedict()を使ったことだ。いわゆるしゃくとり法を用いた。
詳しくはこちらを御覧いただきたい。https://qiita.com/drken/items/ecd1a472d3a0e7db8dce

先にコードを示す。

コード

# dequeをimport
from collections import deque

# input()
n, k = map(int, input().split())
clist = list(map(int, input().split()))

# 初期設定
dic = {}
cnt = 0
temp = deque()
keep = 0

for c in clist:
    temp.append(c)
    cnt += 1

    # もし辞書にcのkeyがなければ、1をカウント
    # あれば、数える
    if c not in dic:
        dic[c] = 1
    else:
        dic[c] += 1

    # keyの数を取得
    len_dic = len(dic)

    # もしkeyの数が今まで以上ならば、keepに保存
    if len_dic >= keep:
        keep = len_dic

    # tempの長さがk以上、つまり、連続する範囲を超えたなら、一番左にある古い値を取り除き、範囲外になったので、辞書のその値から1を引く
    if cnt >= k:
        t = temp.popleft()
        dic[t] -= 1
        # もしvalueが0になれば、そのまま残すと辞書のkeyの数としてカウントされてしまうので、辞書から取り除く
        if dic[t] == 0:
            dic.pop(t)

print(keep)

解説続き

連続する$K$個の色を見ていきたいので、それを保存する場所をつくる。これをキューを用いて実装する。なぜなら、キューにappendpopleftのそれぞれの操作は、計算量$O(1)$で実装できるからである。したがって、ループの中に入れても計算量を$O(n)$に保つことができる。

これと組み合わせて使うのが、dict()である。set(list())で長さを数えればいいじゃないか、という意見もあるが、list()set()にする作業で計算量$O(n)$かかってしまう。したがって、キャンディーの色の種類の保存には、dict()を用いる。例えば、同じ色がキューにappendされたときに、辞書のkeyに当たる部分を探し出し、$+1$カウントしてあげるだけで良い。また、キューから値が出る、popleft()するときは、もし辞書のvalueが0担った場合、辞書のkeyを消してあげることで色の種類を数えることができる。

これをコードに起こしてあげると上記のようになる。詳しい解説は、コード内にコメントアウトしてあるので、そちらをみていただきたい。

編集後記

そろそろC問題で茶diff来そうだなー。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1