パナソニックグループプログラミングコンテスト2023(AtCoder Beginner Contest 301)をPythonで解く

投稿日: 

Atcoder Python

B!
Daniel AgreloによるPixabay(https://pixabay.com/)からの画像

こんにちは, Shinoryoです.

今回はパナソニックグループプログラミングコンテスト2023(AtCoder Beginner Contest 301)を, Pythonで解いてみた結果を書き連ねていこうと思います.

A - N-choice question

先に$\lceil N/2 \rceil$回勝利した方が勝利になります. 高橋くんと青木くんのそれぞれが勝った回数をfor文で調べていき, どちらかが$\lceil N/2 \rceil$回勝利した時点でその人を出力して終了すればよいです.

Pythonにおける切り上げは, math.ceilで簡単に得ることができます.

B - Fill the Gaps

基本的には$A_1, A_2, \ldots , A_N$をそのまま出力し, もし途中で$| A_i - A_{i + 1} | \neq 1$となった場合にはその間を埋めるように出力すればよいことが分かります. Pythonのprint()は最後にデフォルトで改行を加えてしまうため, print(end = " ")のように最後に改行ではなく空白を加えるようにします.

C - AtCoder Cards

  • 順番に$S$に含まれている文字が$T$にも含まれているかを確認する.
    • $S$に含まれている文字が$T$にも含まれていればとりあえずOK. その文字を使うことにして, $T$からその文字を消す.
    • $S$に含まれている文字が$T$に含まれていれなければ, $T$に@が含まれているかを確認する. $T$に@が含まれていれば, その文字を使うことにして, $T$からその文字を消す.
    • $S$に@が含まれていれば, それは$T$における「余り物の」a, t, c, o, d, e, rあるいは@と対応させたいので, 個数を記録して保留にする.
  • $S$に含まれている@の個数分, $T$に「余り物の」a, t, c, o, d, e, rあるいは@が存在するかを調べる. 存在すれば, その文字を使うことにして, $T$からその文字を消す.

以上を通過したらYes, どこかの段階で条件から外れたらNoを出力する.

ミソなのは, 「$S$に含まれている文字が$T$にも含まれてい」るといったことを確認する手段です.

すでに使った文字が消去された新しい$T$を用いて検索をしなければなりません. しかし, ここにリストに対するinを使っていた場合, inの時間計算量は$O(N)$($N$はリストの要素数)であるため, 結果としてTLEになってしまいます.

これは, 文字列$T$の情報を, 「文字$x$が$y$個含まれている」といった情報に変換することです. これを辞書型で実装すれば, inの時間計算量は$O(1)$で済みます. 「$T$から文字$x$を消す」は$y$を$1$減らせばよく, $y$が$0$の場合は文字$x$が$T$に含まれていないものとみなすことにします.

「文字$x$が$y$個含まれている」といった情報への変換は, collections.Counterを用いると簡単に実装できます.

D - Bitmask

まず, 全ての?を$0$に変えたものが, $T$の最小値になります. これによりも$N$が小さい場合, $-1$を出力することになります.

その条件をクリアしたら, $N$を超えないように?を$1$に変えていくことになります. $1$に変えた?が左にあればあるほどその数字は大きくなりますので, 左の?から順に$1$に変えて, $N$を超えないかを確かめていくことになります.

2進法の文字列を10進法の整数に変えるには, int(文字列, 基数)を用います.

E以降

E以降は私の能力不足故に省略いたします.

参考にしたサイト等