Boot camp for Beginners hard 031【D – Preparing Boxes】をpython解説

Boot camp for Beginners hard

Atcoder Problems という競プロを勉強する上でのコンテンツがあります。AtCoder Problems

今回は、hard100問の内、31問目を解説していきたいと思います。

問題名 【D – Preparing Boxes】

入力

N:配列の長さ
ai: (iの倍数に書かれた箱に入っているボールの和)%2

考察

今回問題を理解するのが難しいです

1 以上 N 以下の任意の整数 i について、i の倍数が書かれた箱に入っているボールの個数の和を 2 で割った余りが aiするようにするには、どの箱にボールを入れれば良いですか?

という問題です。例えば

ex)
3
1, 0, 0

1の倍数に入っている(ボールの数)%2は・・・1
2の倍数に入っている(ボールの数)%2は・・・0
3の倍数に入っている(ボールの数)%2は・・・0 になるように箱にボールを入れてください となります。

今回の場合、箱1にのみにボールを入れれば条件を満たし良いのですが・・・

ここで考えなければならないのは、箱1にボールを入れても、2の倍数のとき、3の倍数のときに影響が出ないということです。逆に言うと、箱2を入れてしまうと、1の倍数のときと2の倍数のときの計算に影響が出てしまいます

そのため、影響力の大きい箱からボールを入れるか入れないかを決め、徐々に影響力の小さい箱について探索すれば良いです(なぜならNの箱にボールを入れるとNの約数の結果にも影響が出てしまうため、大きい数から探索し最後に小さい数で調整する必要があるため)

コード

N = int(input())
A = list(map(int, input().split()))


A = [0] + A#1-indexにするために0を頭に挿入
#箱にボールを入れるか入れないかを記憶するリストを用意
box = [0 for i in range(N+1)]#1-indexにするためN+1の配列を生成(0番目は使用しない)
M = 0#何回ボールを入れたかをカウント
ans = []#ボールを入れた箱のindexを記憶


for baisuu in range(N,0,-1):#大きい倍数から探索
    cnt = 0
    for i in range(baisuu,N+1,baisuu):#baisuuの倍数の箱に
        cnt += box[i]#入っているボールの数をカウント
    
    if cnt %2 == A[baisuu]:#もし(baisuuの倍数に入っているボールの数)%2が入力と同じ時
        continue#そのまま
    else:#もし(baisuuの倍数に入っているボールの数)%2が入力と異なる時
        box[baisuu] += 1#倍数番目の箱にボールを入れ
        M += 1#ボールを入れた回数を+1し
        ans.append(baisuu)#そのインデックスを記憶する


print(M)
print(*ans, sep = " ")

まとめ

前の問題
次の問題

コメント

タイトルとURLをコピーしました