−目次
AtCoder Beginner Contest 121 D問題メモ
B - Can you solve this?
解法
そのまま実装すれば良い。
1 2 3 4 5 6 7 8 9 10 |
import numpy as npn, m, c = map(int, input().split())bbb = np.fromiter(map(int, input().split()), dtype=np.int64)ans = 0for _ in range(n): aaa = np.fromiter(map(int, input().split()), dtype=np.int64) if sum(aaa * bbb) + c > 0: ans += 1print(ans) |
C - Energy Drink Collector
問題
- エナジードリンクを売る店が NN 軒ある
- ii 番目の店はエナジードリンクを AiAi 円で BiBi 個売っている
- MM 個のエナジードリンクを集めたい時、かかる最小費用を求めよ
解法
安い店から買えるだけ買う、という方針を素直に実装する。
安い店順に並べるには入力をリストや辞書に溜めて、ソートする。Pythonの場合はcollections.defaultdictを使うと、同じ金額の店をまとめる記述が書きやすくなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from collections import defaultdictn, m = map(int, input().split())ab = defaultdict(int)for _ in range(n): a, b = map(int, input().split()) ab[a] += bans = 0remain = mfor k in sorted(ab.keys()): if remain <= ab[k]: ans += k * remain break ans += k * ab[k] remain -= ab[k]print(ans) |
D - XOR World
問題
- 2つの正整数 A,BA,B が与えられる
- ⊕⊕ を、排他的論理和の演算子とする
- f(A,B)=A⊕(A+1)⊕...⊕Bf(A,B)=A⊕(A+1)⊕...⊕B を求めよ
- 0≤A≤B≤10120≤A≤B≤1012
解法
まず排他的論理和の性質から、f(A,B)=f(1,B)⊕f(1,A−1)f(A,B)=f(1,B)⊕f(1,A−1) である。
f(1,A-1): 1 2 3 .. A-2 A-1
XOR f(1, B): 1 2 3 .. A-2 A-1 A A+1 ... B-1 B
----------------------------------------------------
`-- 打ち消し合う --' A A+1 ... B-1 B
なので、1からNN までの累積排他的論理和が求められればよい。
実験してみる。すると、1桁目とそれ以外を分離すると、特徴が見えてくる。
N bit f(1,N) 0 0000 0000 1 0001 0001 2 0010 0011 3 0011 0000 4 0100 0100 5 0101 0001 6 0110 0111 7 0111 0000 8 1000 1000 9 1001 0001 10 1010 1011 11 1011 0000 12 1100 1100 13 1101 0001 14 1110 1111 15 1111 0000 ...
1桁目の部分は、2進数が0,1,0,1,…となるので、累積XORは0,1,1,0,…となる。
それ以外の部分は NN が奇数の時0となり、偶数の時は NN のままとなる。
D問題にしては、わりと実験しやすく法則も気付けば単純なので、正解率は高かった模様。証明は解説pdfがエレガント。
1 2 3 |
a, b = map(int, input().split())x = lambda n: (n % 4 in (1, 2)) + (0 if n % 2 else n // 2 * 2)print(x(max(0, a - 1)) ^ x(b)) |

