「競技プログラミングを始めたばかりの人にオススメの問題集は何?」というのが普段よく見ている Slack で話題に登っていたので、私の考えをまとめました。
おことわり
私は競技プログラミングを本格的に始めてからもうすぐ5年の水色コーダーです。めっちゃくちゃに強いわけではないですが、基礎的なところはある程度習得している、という感じです。
この記事は、そのような実力の私が、あくまでも独自の評価軸で勝手に評価したものなので異論はあると思います。また、各種学習法/問題集について私自身が全て完走しているわけではありません。
これらをご理解いただいたうえで、以下をご覧ください。
最推し: アルゴ式
2023年1月現在、初心者向けの最初の問題集としてお勧めしたいのは アルゴ式 です。アルゴ式の特徴として次のようなものがあると思っていて、それが初心者が練習するうえで適した特徴だと考えるからです
- ジャンルごとに問題が分かれている
- 1ジャンルごとの問題数がそれなりにある
- ひとつひとつの問題の難易度が易しめ
興味の湧いた人は、とりあえずアカウントを作って問題を解いてみてください。
なお、「競技プログラミングを始めたばかりの人」と言っても、その人の経験によって最適なものは変わってくるとは思いますが、次のような人を想定したときに特にアルゴ式が適していると思います。
- プログラミング自体の初心者ではない。
- 初歩的なプログラミングの概念は一通り把握しているくらいを想定。
- 過去問に取り組もうとしたけど、A問題やB問題でも結構難しいと感じる。
この想定にマッチしない人であれば、次節以降で紹介するサービスや問題セットのほうが良い場合もあると思います。(あるいは適宜併用もお勧め)
プログラミング自体のガチ初心者向け
競技プログラミングだけでなく、プログラミング言語自体もほとんど未経験、みたいな人には書籍 「オンラインジャッジではじめるC/C++プログラミング入門」 がお勧めです。
この書籍を利用すると競技プログラミングのジャッジサービスを利用して、問題を解きながらプログラミングに入門できます。
前述の「アルゴ式」の難易度勾配は非常に緩やかなので初心者に優しいのですが、ある程度プログラミング言語の前提知識が必要なので、ガチ初心者には辛いかもしれません。そのような人はこっちを先にやりましょう。
アルゴ式より先にこちらを先にやるかどうか迷う場合、次にあげるプログラミング言語の基本的な概念をなんとなくでも理解できているかどうかで決めると良いと思います。自信がないならこちらをやればOK。「なんとなくわかるわー」という人はアルゴ式に行けば良いです。
- 四則演算
- 変数 / 代入
- 条件分岐
- 繰り返し
- 関数
- 入出力
- 構造体/クラス
なお、対応するジャッジが AOJのITP1コース にあります。
手っ取り早く強くなりたいプログラミング経験者向け
IT業界でプログラミング経験をそれなりに積んだ人や情報系の学生の人だと、競技プログラミングを始めたばっかりでも「A問題、B問題はそれなりに解けるし、C問題もじっくり考えればわかる」って人はそれなりに居ると思います。そのような最初からある程度強い人や、あるいはある程度競技プログラミングに慣れてきたけど伸び悩んでる初級者、みたいな人にお勧めなのがこちらの「競技プログラミングの鉄則」です。
2023年1月現在、この書籍は競プロジャンルにおける最高峰の知の高速道路です。
この書籍は、近年の競プロで頻出の典型アルゴリズムや考察法を効率よく学ぶことを重視した内容になっています。一方で競プロであまり出題されないアルゴリズムの学習は重視していません。例えばアルゴリズムの学習カリキュラムには普通必ずと言っていいほど登場するソート(整列)についてはライブラリとして利用するのみで、それらのアルゴリズムやデータ構造そのものの解説についてはほとんど登場しません。競プロのコンテストにおいて、ソートはライブラリとして利用することはあっても自分で実装するケースはほとんどないので、適切な割り切りだと思います(特定のソートアルゴリズムを知っていると有利な問題が出題されることはありますが、頻度は低いです)。
各問題の解説は丁寧かつカラフルな図が多様されているので、各アルゴリズムの「気持ち」を直感的に理解しやすく、難しめのアルゴリズムでも容易に習得できます。プログラミング経験をそれなりに積んでいる人は、いきなりこちらの書籍で学習を開始すると効率が良いと思います。
この書籍に対応するジャッジがAtCoder の 常設コンテストとして公開されています。
基礎をじっくり固めたいプログラミング経験者向け
さきほどの「競技プログラミングの鉄則」はすでに書いた通り、近年の競プロですぐに強くなるために必要なことを重視した、割り切った構成になっています。コンテストで手っ取り早くパフォーマンスを出すのが目的なら最適ではあるのですが、この本だけだと各種ソートアルゴリズムのように「初歩的なアルゴリズムなのに知らないし書けない」みたいなところがどうしても出てきてしまいます。そのようなところをカバーしたい、あるいはコンテストのパフォーマンスはあまり気にせず基礎からじっくり取り組みたい、みたいな人にお勧めなのはこちらの「プログラミングコンテスト攻略のためのアルゴリズムとデータ構造」です。
これは上で紹介した 「オンラインジャッジではじめるC/C++プログラミング入門」 の続編という位置付けの書籍です。
こちらの書籍に対応したジャッジは AOJのALDS1コース をはじめとした各種コースにあります。
その他
ここまで紹介してきたサービスや書籍はあくまでも私独自の基準で考えた結果です。経験や好みによって合う合わないはあると思うので、その他の候補をまとめて紹介します。これらについても順番にやるよりも複数を併用していくのが一番良いかもしれません。
競プロ典型90問
初級者〜中級者向け。初心者が最初に取り組むのはやや難しいかも。「アルゴ式」から初めて、次に「競技プログラミングの鉄則」を終わらせたら 「競プロ典型90問」で腕試し、というルートが良さそう。
前述の書籍「競技プログラミングの鉄則」の著者である E869120 さんが主催する 競プロ典型 90 問は、競プロ参加者のモチベアップや各種典型力向上を目的として実施された企画です。AtCoderで常設コンテストとして設置されています。
問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本
数学に関連した問題に特化した問題集。全体的な難易度は「競技プログラミングの鉄則」よりもやや下、といったところだが、一部の問題はより高度な内容だったりもする。競技プログラミングにおいては、普段使わないような数学の概念を要求されることがあり、それらに苦手意識がある人にお勧め。
ちなみにこれも E869120 さんが書いた本です。
プログラミングコンテストチャレンジブック [第2版]
言わずと知れた日本の競プロ界のバイブル。これまで紹介した書籍等と比較すると発行時期はかなり古いが、内容は現代でも全然通じるうえ、他の書籍にはのっていない、かなり高いレベルのアルゴリズムまでカバーする。ただし、それゆえ難易度勾配もきつく、初心者にはあまりお勧めできない。一部の優秀なエンジニアや情報系トップクラスの学生だと、この本が一番話が早いかもしれない。
ABC過去問埋め
ある意味王道。レベルの幅と問題数は圧倒的。この学習法においてはACした場合であっても解説や高レベル参加者の提出コードを読むなどの振り返り学習が重要。また、全埋めを目標にすると達成が遠すぎて挫折しやすい。
AtCoder Problems のテーブル表示でAtCoderのユーザIDを指定すると、そのユーザが各問題にACしているかどうかを見ることができるので、それを利用してABCのA問題やB問題など難易度の低い問題から順にAC状態にしていく(埋めていく)学習法のことです。
バーチャルコンテスト
こちらも王道。過去のコンテストの問題セットを使ってバーチャルなコンテストを開催できるので、本番と同じように時間を区切って解いていく。他の人が開催しているコンテストに乗っかるのもあり。コンテスト本番と同じように時間制限や順位表示などの各種プレッシャーを再現できるので非常に有用。
なお、複数コンテストから問題を選ぶことも可能。また、AtCoder Problemsのバーチャルコンテストでは、指定した難易度の問題を自動選択してくれるBacha Gacha機能があり大変便利。
おわりに
競技プログラミングを始めたばかりの人にオススメの問題集は以上になります。紹介しきれなかった書籍や問題セットもたくさんあります。みなさんのオススメがあれば、コメントで教えてください。