AtCoder Beginner Contest 127 D – Integer Cards をPython3で解く

Share

AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。

出典:
AtCoder Beginner Contest 127 D – Integer Cards

問題を読んで最初に思いついたのは、優先度付きキューを用いたシミュレートだったが、制約が \(1 \le N \le 10^5, 1 \le M \le 10^5 \)で、最悪 NM 回行うことを考えると間に合わなさそう。なので、真面目に考察を行う必要がある。

カードに書かれた数字を書き換えると考えると一見面倒くさそうだが、新たにカードを引き、その際に一番数字の小さいカードを捨てる、と考えると見通しが立てやすいかも。

# AtCoder Beginner Contest 127 D - Integer Cards
# https://atcoder.jp/contests/abc127/tasks/abc127_d
# tag: 考察

# 最大効率でカードの交換を行った場合、結局のところ
# 最初に持っている数字 + 書き換え後の数字 の集合から
# 上位 N 枚のカードを選んだのと同じ状態になる。

# というわけで、全てのカードを数字ごとに整理しなおし、
# 上位 N 枚の数字の合計を求めることにする。
def main():
N, M = map(int, input().split())
A = list(map(int, input().split()))
changes = [list(map(int, input().split())) for _ in range(M)]

# カードの数字ごとに何枚あるかを保存
cnt = dict()

# 最初に持っているカードを数える
for a in A:
if a not in cnt:
cnt[a] = 0
cnt[a] += 1

# 書き換え後のカードをカウントに加える
for b, c in changes:
if c not in cnt:
cnt[c] = 0
cnt[c] += b

# 数字を大きい順にソート
cards = list(cnt.keys())
cards.sort(reverse=True)

# N 枚になるまで大きい数字から順番に取る
taken = 0
result = 0
for card in cards:
n = cnt[card]
if taken + n < N:
result += card * n
taken += n
else:
n = N - taken
result += card * n
break

print(result)

main()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です