問題
C – 高橋くんと魔法の箱
回答
スライドに従い、50点回答を求めます。
AtCoder Beginner Contest 019 解説 from AtCoder Inc.
N = int(input()) a = list(map(int, input().split())) #ある数 x に対する結果と 2x に対する結果が同じなので, # a[i] が2で割り切れなくなるまで2で割り続ける。 # この処理で,a[i] がすべて奇数になった問題になる。 # 逆に,奇数で異なる数に対する答えをまとめて求めることは不可能。 def divide_by_2_till_odd(x): while x % 2 == 0: x //= 2 return x a_odd = list(map(divide_by_2_till_odd, a)) # 20点解法 # n<=3000 なので,a[i] が a[j] (1<=j<i) のいずれかに等しいかをすべてチェックし。 # いずれにも等しくないとき,ai の種類を1増やす def solve20(a): cnt = 0 for i in range(len(a)): for j in range(i): if a[i] == a[j]: break else: cnt += 1 return cnt #30点解法 # a[i]<=300000 なので,ある数が現れたかどうか, # という長さ 300000 の配列を取り,それぞれのa[i]について,現れたことをメモする. # 最後に現れたことのある数を数える. def solve30(array): memo = [False] * (5 * 10 ** 5 + 1) for a in array: if memo[a]: continue memo[a] = True return sum(memo) if N <= 3000: print(solve20(a_odd)) else: print(solve30(a_odd))
AtCoder Beginner Contest 019 解説 from AtCoder Inc.
集合を使い、100点回答を求めます。
N = int(input()) a = list(map(int, input().split())) #ある数 x に対する結果と 2x に対する結果が同じなので, # a[i] が2で割り切れなくなるまで2で割り続ける。 # この処理で,a[i] がすべて奇数になった問題になる。 # 逆に,奇数で異なる数に対する答えをまとめて求めることは不可能。 def divide_by_2_till_odd(x): while x % 2 == 0: x //= 2 return x # 集合を使う a_odd_set = set(map(divide_by_2_till_odd, a)) print(len(a_odd_set))
ソートを使い、100点回答を求めます。
N = int(input()) a = list(map(int, input().split())) #ある数 x に対する結果と 2x に対する結果が同じなので, # a[i] が2で割り切れなくなるまで2で割り続ける。 # この処理で,a[i] がすべて奇数になった問題になる。 # 逆に,奇数で異なる数に対する答えをまとめて求めることは不可能。 def divide_by_2_till_odd(x): while x % 2 == 0: x //= 2 return x # ソートを使う a_odd_sorted = sorted(list(map(divide_by_2_till_odd, a))) cnt = 1 for i in range(1, len(a_odd_sorted)): if a_odd_sorted[i-1] == a_odd_sorted[i]: continue cnt += 1 print(cnt)