純粋培養プログラマが就活を意識して Python で ABC を解く [Day 1]

競技プログラミング解説記事

このシリーズの目的

就活を少しだけ意識して綺麗な Python コードを書けるようになる。そのため、出来るだけ綺麗で分かりやすいコードを書くことが目的。(そのため、for文でゴリ押しして PyPy で提出、といったことはしない。)

今回解くコンテスト

ABC 203 (Sponsered by Panasonic)

Tasks - AtCoder Beginner Contest 203(Sponsored by Panasonic)
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

A問題

同じ値があるかないかどうかは、ソートして調べると簡単に分かる。

B問題

やるだけ。

C問題

ペアに対して、「第1要素を優先したソーティング」の処理が要求される。

D問題

苦戦した。二分探索をした後は、累積和を使って高速に数を数えるだけなのだが、その処理を純粋に実装するとTLEとなる。理由としては、Pythonの二重ループが遅いためであると考えられる。

ACするために今回行った工夫は、以下の通り。全体として、「ループを素直に実装しない」という方針で工夫を行なった。

  • 配列の確保の仕方
    • C++なら適当な配列を用意するために普通にループを回していたが、今回はnp.where (〇〇な部分は■■にする、といった処理)と np.insert(0-indexの配列を1-indexに移すために使用)を用いた。
  • 累積和の計算
    • ループを回して累積和を計算するのではなく np.cumsum を用いる
  • スライスを用いた高速な計算
    • 各 \(K*K\) 領域に含まれる数の総和がいくつかを高速に判定したい。そのために、切り出した二次元配列同士の加算・減算に帰着させた。

感想

numpyやリスト内包表記にもっと詳しくなりたいです。(普段Pythonで競プロしてる人ってこんな大変なことやってるんですか……?)

コメント