Posted at

競技プログラミングのA問題を1時間かけていた自分がC問題やっと自力で解けるようになってきた話


はじめに

こんにちは、みなさん競技プログラミング生活はいかがでしょうか。ぼくは相変わらずAtCoder Beginners ContestでもA、B問題がやっとの状態です。

でも最近C問題の過去問がやっと自力で解けるようになってきたんですよね。ということでそこまでの道のりを日記的な感じで書いていきたいと思います。書いている言語はpythonです!

ガチプロのかたは。。。まあスキップしてください汗。


1.学科同期の速すぎる成長度にびびる

去年からプログラミング学び始めた同期が春休み中にめっちゃ過去問を解き、そのおかげで急成長を遂げたという話を先週ぐらいに聞きました。

その同期が言うには、春休み中に過去問のC問題をひたすら埋めていったようです。

AtCoderの過去の問題を解くと、Atcoder Problemsというサイトで自分の成長率などを表示してくれます。めっちゃかっこいいです。以下はぼくのではなく()、どこかのガチプロさんの画像です。

image.png

結構同期が周りでもやっていて、ちょっと自分もやらねば、と思わされたのでした。


2.C問題1日1問を目標に頑張るが。。。

ということで自分もC問題をどんどん埋めていこう!と思ったわけです。1日1問を目標にしてできるだけ自力で解こうと思いました。

しかし、ぶち当たる問題すべてが新しいものだらけでつらい。。。という状況が1週間ほど続きます。動的計画法、累積和、累積GCD、と数学Aの整数、確率あたりがもともと苦手だった自分は発狂しそうになりました(明らかに向いてない)。

やっぱ来世からやり直したほうがいいか、、、と思いつつもなんとか近くのデニーズで頭が痛くなるまで頑張ります。

自分は以下のような勉強法でC問題を解いていきました。

・1時間半の制限時間を自分で設定して、C問題を解いてみる。

・時間オーバーしちゃったら答えのpdfをみて、そのpdfで言っていることをpythonで実装してみる。
・それでもし余裕があったらそのpdfに書いてあることをqiitaで検索する。
を繰り返す。


3.ときどき閃くようになる

と言いつつも、なんとなく傾向がわかってくるんですよね。Nがとてつもないオーダーあたりになるような問題でも、「どうせこれを簡単にO(n)で計算する方法がどっかにあるはずなんだろ?!」と反骨心が芽生えるようになりました。

2秒以内に計算しないといけないわけだから、そんな何回もfor回させるわけがない、と考えられるようになってきました。

なにも無理やりforやifを多用しなくてもいい。そうやって自分をリラックスさせることでひらめきに近づけるようになりました。これがお風呂に入っている時とか、電車に乗っている時とかにシンプルな解法をひらめくきっかけになっていったのだと思います。


4.コードを書くより、まず考えるようになった

始めた時はpythonのsetとかtupleの違いもうろ覚えなので(おい)、コードの実験とかでめっちゃ時間をとられていました。あと入力の読み込みとかも効率のいい読み込み方法などを探すためにコンテスト中に30分ぐらいそっちに割かないといけなかったとか(向いてない x 2)。

ですがだんだん慣れてくると、その「コードを書くためのコード」の実験部分が必要なくなってくるためなのか、考えることに時間を割けるようになりました。

「実装はできるはずだから、まず手順を考えよう」みたいな。

以前はjupyter notebookで手を動かしているのが、だんだん紙のノート上で手を動かすのが増えていった気がします。

でもこれは結構重要なシフトだと思いました。自分は「自分が効率よくやっている」ことを自分に言い聞かせるためにコードを書いているくせがあった(ある)と思います。

でもこのシフトができるようになったのもpythonの使い方がだんだんわかってきたからだと思いますし。「コードのためのコードを書く」ことと「コードを書かずにまず考える」を同時にやってこそ相乗効果が見込めるのかもしれません。


結論

自分成長していない、、、と思う時が一番つらいけど、

苦しんでもがいているのも成長の大事な部分だぞ。

冬が過ぎてこそ春が来る。ということをはしくれながら学んだ気がします。

これからもC問題できるだけ毎日解いていこうと思います。まだまだ先は長いぞ。。。