shikoan’s memo

プログラミング初心者のチラ裏

ぷろぐらみんぐ帳

AtCoderに登録してみた

前々から気になっていたAtCoderに登録してみた。Beginners Sectionの10問全てと過去問のA~Dの10問ちょいを解いてみた(あんまそこまで本気でやるつもりはない)。

abs.contest.atcoder.jp

AtCoder Problems

レートがつく大会に出ていないので晒すほどのプロフィールではない。探せば出てくるはず。

言語はC#で。C++推奨とか書いてあるがあんな黒魔術やりたくない。LINQ最高~。見える……ガバガバ実装でメモリや処理時間バカ食いする未来が!(言ったそばからBeginnersのC問題でTSEやMSEを出したで自分が通ります)

以下、noobのチラ裏なんで真に受けないでね!!

メモリの制約、実行時間の制約

競技プログラミングということで、メモリアロケーションの制約、実行時間の制約が大変厳しい。2秒で256MBの制限なら、1つのテストケースで0.1秒でもオーバーしたら不正解扱い、途中計算でちょっとでもメモリ使用量オーバーしたらアウト。「えー最後にGCで回収するしいいじゃん(バンバン)」は通用しない。ここが競技プログラミング、厳しい。
逆に言えば、採点ケースで通過すればいいので、実装は正しくなくても想定している答えを出せば正解扱いになる。極端に言えば、全てのテストケースとその答えを知っていたら、if文なりswitch文なりで入力に対応する答えを出力するだけで正解になる。ここが面白いところ。
あと回答時間の制約や不正解のペナルティもあるが、時間制約のあるコンテストをやったことがないのでなんともいえない。過去問見るとあれを時間制限ありで正解を解くのは結構きつい気がする。処理時間さえ許せば速く書けるほうがいいので、あとで見返した際の可読性はよろしくないと思う。100点の美しいコードをじっくり書くよりも、70点ぐらいで速くかけるほうを目指したほうがよさそう。

競技プログラミングではないが、似たようなプログラミングで問題を解いていくサイトとしてProject Eulerがある。こっちは昔やっていたことがあって時間をかければ150問ぐらいは解けた。

projecteuler.net

こっちはメモリ制約も時間制限もなくて答えを入力するだけ。想定としては「上手く実装すれば全てのケースで1分以内に処理が終わりますよ」とのことなのだが、そんなのチェックしていないし(なぜなら問題の回答の値を1個入力すればいいだけなので)、裏でこっそり1日ぐらい処理を回してようが、メモリをギガバイト単位で使っていようがばれっこない。回答としては美しくないのだろうけど。じっくり派の人はこっちがいいかもしれない。ただオイラーの名の通り数学要素が強いので、好き嫌いはあると思う。

難易度別雑感

ABC(AtCoder Beginner Contest)での難易度基準です。

A問題、B問題:プログラミングある程度やっている人なら一目で解けるやつ。B問題は一瞬ん?と思うけどああ、そうやるのねってなる感じ。将棋で言う所の詰将棋の1、3、5手詰めぐらいの感覚だと個人的には思う。
ただプログラミング初めてすぐの人だとこれ解くのも結構苦労すると思う。A問題、B問題の知識は競技プログラミングやらずに、普通にプログラム書く場合も全然使うので、単なるプログラミング学習教材としてもかなり有効。ここらへんが一目で解けるようになったらもうプログラミング初心者じゃない。大学でプログラミングの入門講義があるとしたら、AB問題余裕で解けるようになったら一切出席しなくても単位がくるレベル(もちろん出席点で足切りされたら知らないし、AtCoder1日やっただけのガバガバ基準なので自己責任で!)。

C問題:ちょっとトリッキーになるが、整理すれば解ける。問題によってはD問題より難しい(というか慣れてなくて、テストケースで通っても採点のケースでハマるというのがよくある)。Cぐらいになると計算量を頭の片隅ぐらいにおいておかないといけない。詰将棋でいうところで5手~9手ぐらいなのかな。C問題は解けても9手詰めなんてまず解かないからここらへんの感覚はよくわからない。
ただ、競プロの強い人のを読んでいると、最初はアルゴリズムよりもデータ構造で殴ればよさそうなので、データ構造の話なら普通のプログラミングでも結構生きると思う。例えば、どんどん末尾に追加していく処理で、リストじゃなくて配列を新たに作って追加するのやめちくり~~という話(まさかこんなことをする人はいないとは思うけど、世の中にはわれわれの想像を下回るウンコードが存在するので侮ってはいけない)。アルゴリズムに興味なくても、計算量はやはりどこか頭の片隅においたほうがいい。

D問題:E以降は解いていないが、ここは得点によって難易度が違うように感じた。配点100点や200点ぐらいのはものによっては一目なのもあるが、600点の問題は取っ掛かりすらつかめないのもある。というかどう解くのか教えて。
ここらへんからはアルゴリズムを知っていかないとダメな感じはする。こういうのは普通にソフト作ってても覚えられない。「なら、何の役にも立たないじゃないか!」と思うかもしれないが、組み合わせ爆発に立ち向かう姿勢はとても意義のあるものだし、いざというときのブレイクスルーにはなると思う。少なくともこういうので殴り合う世界ではあってもいい。

プログラミングはじめての人はAB問題中心に解けばいいし、腕に覚えがある人はCD問題中心に解けばいい。なるほど、初心者も上級者も楽しめるようによくできている。

覚えてみればコンテストのあるときに腕試しで出て見るかもしれない。意識が低すぎるので忘れてて時間すぎているか、運良く覚えていて出れたとしてもガチ勢にボッコボコにされる未来しか見えない。CD問題は暇な時に解いてみたい。

何がいいたかったかというと、A問題B問題解ければ一般人よりはかなりプログラムできますよということ。

おまけ:「組み合わせ爆発」でググってたら科学未来館が意味深な動画を出していた。結構有名?

www.youtube.com