OMC209の後記

こんにちは、リユナです。

今日のOMC209に出て、9位になる大活躍をしました!あとGのFAもしました!

ちょっとだけミスがあったんですが、でも久々のいい成績で嬉しいです!

では、今日の後記始めます!

G(4分、FA)

初めからなんか解けそうだったので挑戦。式を整理すれば結局(1からAまでの総和)、(1からBまでの総和)、(1からCまでの総和)の式で表せます。実は3の倍数のほうがはるかに多いので、3の倍数ではない場合を割り出すことが易いです。Aまでの和とCまでの和は3の倍数ではなく、Bまでの和が3の倍数になる場合の数を計算して、全体から引く。

初めてはA<B<Cを見てなかったので1ミス。

A(1分)

幾何ですがすぐ解きました。半分にして90度合わせたら正解。

B(54秒)

最初の条件から(x-23)^2+cの形で表せます。後は何とか。

C(2分)

1000a+100b+10c+dのことを勘違いして1と7、2と8、3と9が反対になりましたね。a, b, c, dは差が-6, 0, 6の中の一つなので3^4=81

D(4分)

まずあいこにならない数を数えます。これは「3種類のことの中で7個選んだ時それが全部2種類になる場合の数」なので、3C2*(2^7-1^7*2)でできます。あとはA君が勝つ場合と負けるのは対称だから半分すればいいです。

E(2分)

1とすべての素数に対して素数自身、または素数のk乗が入れば丁度要素数26の集合になりますね。2は6乗まで、3は4乗まで、5と7は2乗までできるので6*4*2*2=96

H(5分)

数列の以下の項の数を基準として探しながら規則を探して解きました。二つの場合が大事。

F(16分)

Hを全部解いて、Hの提出をここにして1ミス

一応日本語の翻訳が難しかったんです。DがAを中心としてBの対称点か?!と思って全然違う問題を解き始めました。後はこれを直して、スチュワートの定理を何回か使って体育で解こうとしたんですが計算ミス(多分)で1ミス。ECと平行する直線をAから描いて、これとBCの交点をFとしたら、BCDとCFAが相似となりますし、

EBCとABFも相似。これと角の二等分線の性質で何とか頑張って解きました。

総評

(今気づいたんですが、前の記事、総評の漢字が間違っていましたw)

Gのような、好きなタイプの問題がちょっとあって好きでした。全部そんなに難しくはないが面白くてよかったんです。4bとしては最高成績ですよね。早く全問完了して、あとGのFAも嬉しいですね!

ミスがちょっとあったのと、日本語の翻訳の問題でちょっと迷ったのが惜しいです。でも仕方ないですね。これは私がもっと日本語を勉強すればいいと思います。

とにかく、最近OMCがよくできなかったんですが、今回は結構いい成績が出てとても嬉しいです!

OMC206の後記

こんにちは、リユナです。

今日のOMC206に出て、4位になる大活躍をしました!

実は今日の整数論の授業がちょっと遅く終わって、少しペナルティがあったんですが、それに負けず素晴らしい成果を出て嬉しいです!

では、今日の後記始めます!

A(1分)

9の倍数になるためにはすべての桁の総和が9の倍数になればよい。あと、11の倍数は、偶数番目の桁と奇数番目の桁それぞれの総和の差が11の倍数になればよい。前者はnが9の倍数、後者はnが偶数の時成立するので答えは18です。

E(25分、1ペナ、FA)

前に競プロの作問をしながらほぼ同じことを勉強したことがあって助かりました!運がよかったんですね。

垂直についている2点をまとめて順番対で考えた方が楽です。 大体そんな風に漸化式を求めて、とにかくうまくやれば最終的に式が出てくるんですが、意外とそこで1237で割った余りを手に入れるのがなかなか難しかったです。

私は初めてのことを固定させていて、最後に6をかけることを忘れて1ペナでした。🥲

B(6分)

幾何に見えますがあんまり幾何的な要素が多くなかったので考えより早く解けました。A1A2Pが二等辺三角形になるのがポイントでしたね。角二つの値を未知数として式を整理すると範囲が出て、あれを満足するnは4以上10未満になりました。が。nが4になればPとQが辺の上に乗るのでだめです。5+6+7+8+9=35。

C(6分、1ペナ)

コインが合わせて14個あります。これらをまず配って、みんなに“配ったコインの数+1”の枚数の1万円札を配れば1万円札はちょうど1個残ります。これを誰に配るかを考えたらいいです。

私は初めて「五郎君」を見なくて、“あ、四人あるんだな”と思って1ペナしました😂

D(10分、2ペナ)

FAできて嬉しいです!実は、昨日解いた競プロの問題と使われるアイデアが同じで助かりました。

7!=2^4*3^2*5*7で、ある約数dを、square-free(つまり、1以外の平方数で割り切ってない数)な数pと正の整数qに対して、pq^2として表せると、集合の中でpが同じ数字が二つ以上あればだめです。pで出来る数字は2, 3, 5, 7それぞれが一回かけられるかないかの場合を全部数えたら2^4=16になります。つまりn=16です。

後は総積ですね。基本的にpq^2の形にできると言って、pは1, 2, 3, 5, 7, 2*3, 2*5, 2*7, 3*5, 3*7, 5*7, 2*3*5, 2*3*7, 2*5*7, 3*5*7, 2*3*5*7の中の一つで、それは絶対変わりません。問題はqですね。7!の約数の中の平方数は1, 4, 9, 16, 36, 144の六つがありますが、特定何個の数字にはq^2として使わないこともあります。例えば、16=2^4ですが、7!にも素因数2は四つしかないので、もう2を含んでいる要素には16や144はかけられません。まあそんな風にしたら、総積の総和が計算できますね。2^16*3^16*5^24*7^16です。残りは約数の数を計算すればばいいです。

F(20分、1ペナ)

見た目より難しい過ぎて面白かった問題。まずは(a_n+a_n+2)/(a_n+1)の値が一定なのでa_3、a_4だけ整数になればそのあとは問題ないです。

a_3を考えたら、まずkを3で割った余りが1になることを確認できます。同じようにして、a_4を割り出す時にはkを64で割った余りが9になるのを確認できます。中国の剰余定理によって、k=192a+73の形になればいいんです。

ただし、ここに罠が一つあります。kが3913だったら、a_nが負数になることが起きます。すなわち3913を抜いて、73から3721までの総和を計算します。私は初めてはこれを気づけなかったので1ペナしました😢

総平

元々無印が一番得意だったし、しかも幾何がほぼないセットだったので私にとっては本当に有利なセットでした。しかも今回は私がある程度知っている内容が出るなど、運がすごくついてくれました。だが、ペナが少なくなかったので順位がちょっと下がったのは惜しいですね。ペナが2つだけ減ると1位になってたかもしれませんので、それがちょっと惜しかったです。

でも今までの中の歴代最高の成績だったので嬉しいです!問題は全部面白かったですが、特に最後のFの接近が面白かったんです!

おまけ

もうすぐで入黄です!多分次回やその次にできると思います!これからも頑張ります!

AtCoder 入青しました!(+ユリ漫画のおすすめ)

こんにちは、リユナです!

AtCoderでやっと入青しました!

実は初めからパフォ2400ですぐ入水したので、入(何か)は今回が初めてで嬉しいです!もちろんこどふぉでは入橙の経験までありますが、基本的にこどふぉよりAtCoderのほうがレーティングを上がりにくいですので、AtCoderの青ならこどふぉの紫以上だと思います。

それで、今まで頑張って最近のARCで入青に成功しました!今までの入青のための旅を繰り返してみます!

1. 初めまして!AtCoder!と休み

私の初のAtCoderは2022年の11月でした。

確かに初のAtCoderだったんですが、ABCDを解いて、なぜかGを解いてしまって2400というとんでもないパフォーマンスが出ちゃって、すぐ入水しましたwこれで「なるほど、AtCoderって実は易いかも?」とおもいましたが、私は大きいミスをしました。それは

Codeforcesとは違って、AtCoderは参加登録して受けないとレーティングがめちゃくちゃ下がるのを知ってませんでした!!!

すぐに墜落してしまい、私はやる気を全部失って水に復旧だけさせておいてアトコーダーから手を離しました。

大体こんな風にですね。

2. 復帰。入青を目指せ!

昨年の11月くらいに初めて日本の競プロerさんたちと繋がれて、そのあとからまたAtCoderを再開しました!

あの時まで「私はこどふぉ橙だから、すぐ入黄まで問題なさそう!」と思いましたが、実はそうでもなかったし、実力は競プロを休んだ何年間めっちゃ下がって、それにAtCoderはこどふぉとはレーティングのシステムがちょっと違うのを知らなかったんです。簡単に言うと、こどふぉは1、2回うまくやればすぐに上がって、1、2回ちょっとミスったらすごく下がりますが、AtCoderはその程度がはるかに少ないです。

それですぐ1200から1600まで行くのは無理でしたね。12月まで定期的に参加しながら、前の実力を取り戻そう!という感じで頑張りました。

まあこんな時期でしたね。

 

3. 4連敗。やる気消失

順調に行ける!と思ってましたが、すぐスランプが訪れてしまいました。12月から1月までずっとどんなコンテストをやっても問題があんまり解けなくて、確かに解ける問題でもミスって、4連敗までしました。あの頃私は短期留学の準備と祖母の突然のお葬式などで忙しかったりして、さらにめちゃくちゃだったと思います。

「やっぱり私はまだまだダメかな」と思いながらも、ずっと練習をやり続けて、シンガポールに到着しても競プロはやり続けました。この時期から「AtCoderが終わった後、Twitterのスペースで日本語で解説を読みながら復習する!」ということを始めましたが、競プロと日本語の勉強の両方にめっちゃ役に立ちました。

 

4. 復活。5連勝で入青!

シンガポールの生活に慣れたからは安定しているせいか、その間の練習が功を奏したのか、すぐにまた調子が良くなって、レーティングがすぐに上がり始めました!上がるスピードが本当すごいですね!

すぐ1400、1500を超えて、前のARC171で363位をしてやっと入青に成功しました!

 

5. 入青のために勉強したこと

・実は競プロで使われてるアルゴリズムだとほぼ全部読んでみたことくらいはあるので、今の私に必要なことは新しいアルゴリズムの勉強よりは、知ってることをよく実装して、問題をすぐ把握して解くのだと思ったので、今まではBOJの問題をゆっくり解きながら勉強しましたが、過去のABCやARCのバーチャルで本物のコンテストのように練習しました。

AtCoderACLという強すぎる武器があります。私はセグ木が苦手でしたが、ACLの力であの恐怖を克服しました!ACLの使用になれるように練習しました!

・私個人的には、大会で使われてるアルゴリズムの八割以上は「アルゴリズム自体がむずかしい」ではなく、よく知られたこと(動的計画法、二分探索、BFSとDFSなど)をどうやって使ったらいいか?をテストすることに近いと思います。特に、入青までは先に言及したことたちと、Union Find、累積和、imos法、セグ木の基本だけで解ける問題だけ解いてもできると思います。入黄以上は私もまだまだですから、確実に言えませんね😢

・自分の強みである「数学力」を使って、数学的な分析ができる問題はできる限り頑張って数学的に考えました。これは皆の武器は各々違いますから、自分が一番自信のあることをよりよく使えるようにすればいいと思います。

・入青のためには基本的な競プロ数学は知っておいたほうがいいです。場合の数とかは競プロでも定番で出てくるタイプなので、簡単なものから練習することをおすすめします。例えば、私が入青したARC171番のB番も、「順列のサイクル」と「順列の可能な場合の数」を探す問題であり、この点を把握していれば、計算さえ少しで済む簡単な問題ですが、分からないとかなり近寄りがたいと思います。

・復習は徹底的に! 特に「解はほとんど分かった気がするが、結局ACに失敗した!」という問題があればなおさらです!私は日本語でスペースを進行しながら日本語の勉強を兼ねて復習しました。

 

6. おすすめのユリ漫画

めっちゃ関係なさそうですが、これいつかはやってみたかったので、突然ですがユリ漫画のおすすめをします。

 

6.1. やがて君になる

(東方プロジェクトの2次創作ではない)ユリ漫画の入門作品です!今は8巻で完結されました!

王道的な展開の少女漫画、ところがもうその対象が全部女性である。 こんな感じです。 予想した方もいると思いますが、あそこにいる黒髪学生会長のお姉ちゃんが、右側にいる背の低い学生にすっかりはまってしまいます。 感情の変化の描写や高校生が恋をしながらしそうな悩みなどについての描写が本当に細かく表現されていて大好きです!二人の物語が一体どのように進むのか気になる方はこちらへ!

そして、2018年作のアニメも本当すごいです。よかったらどうぞ。(私は舞台探訪までしました。)

 

6.2. ささやくように恋を唄う

やはり素敵な展開の学園物です。右の子が左のバンドの先輩に「一目ぼれしました!」(フォン的な意味)って言ったんですが、左の先輩はあの瞬間めっちゃ右の子にはまってしまい、それから始まる面白くてドキドキする漫画です。

なお、今年4月からアニメ化予定だから、今こそがこの漫画を見るのにちょうどいい時期です!

 

6.3. 私の百合はお仕事です!

名前がこうして初めてはちょっと心配しましたが、本当にユリ漫画です!

(多分マリみてのような)コンセプトカフェで働く高校生たちの話です!ここでのユリは「仕事」に近いですが、実は本当に心を抱いている人たちも相当で、なんとかかんとか。 アニメも面白いのでぜひ見てください!

 

6.4. 熱帯魚は雪に焦がれる

これは「めちゃくちゃユリ!」っていう感じではないんですが、穏やかだが確実に流れていく学園背景の漫画です。二人の高校生がお互いに力を合わせてぶつかりながらも成長していくほのかな叙事と細かい描写が気に入った作品です!

因みに9巻で完結作です!

 

6.5. リ'ドラフト(おまけ)

こちらは連載真っ最中の韓国のウェブトゥーンで、別に日本語の翻訳版があるわけではないと知っているので、とりあえずおまけとして入れるのですが、最近私が一番ハマっている作品の一つなので、ぜひ入れたかったです。

女子プロ野球が興行している世界で、万年有望株だった引退捕手の璘(ナ・リン)は、解散してしまった自分のチームとつぶれてしまった自分の選手生活を取り戻すためにタイムループを重ねるが。。。?

こちらも厳密に言えば直接的な恋愛描写があったりはしませんが、数多くの女性キャラクターの固い絆と感情線が絡み合って対立する姿、スポーツものがお好き、ということで(そして韓国語ができるなら😢)ぜひご覧になることをおすすめします! もう一度言いますが、私は普段、韓国の漫画やウェブトゥーンをあまり見る方ではありませんが、これ一つには最近本当にハマっています!

 

以上でポストを終わります。 百合「漫画」だけでなく、ライトノベル原作などの作品も次回はもっと紹介したいと思います。 次回はたぶん私が入黄する頃ですが、その前にでももしおすすめしてもらいたいことがあればいつでも聞いてください。 ありがとうございました!

OMC205の後記

こんにちは、リユナです。

実は競プロ以外にも私は最近競技数学を始めました!日本のみんなと交流する前には全然存在すら知らなかったんですが、楽しそうで何回参戦し、今は堂々と青solverです!

。。。実はRatedたった四回でこのレーティングで、すぐ入黄まではできそうですw

それでは、後記始めます!

D(5分、FA)

まずは何か一つでもFAしようとしてDとEとFから読みました。Dが面白そうですぐ解き始めました。

典型的な場合の数の問題でした。6999までの数がちょうど1665個だったので、7000以上の最小値を探せば正解!

 

E(5分)

次はEでしたね。今学校で整数論を頑張って勉強してるので私にはもっと有利な問題でした。結局d(n)で出来る数は4, 9しかなかったんですね。これで何とか。素数を数えるのが一番面倒でしたw

 

A(1分、1ペナ)

次はFを考えたんですが、私にはあまりにも難しい幾何問題だったので少し考えてあきらめてAから順に解くことにしました。

見た瞬間解ける易い問題ですが、初めてはPの値を計算するのだと思って1ペナ😢

 

C(5分、1ペナ)

Cもユークリッドの互除法を使えば接近できます。二つの最大公約数は|100-k|ですし、結局99!-1は1から100までのすべての数に対してお互い素ですから、k=100の場合以外は全部できます。ただし、私は計算ミスで1ペナ、200を外して1ペナ合わせて2ペナしました😢

 

B(10分)

10分もかかる問題は絶対なかったんですが、私の下手な日本語の実力が一役しました。

こんなミスをして、めっちゃムズイ問題を創造して解いて、12/95*4^1/3じゃん?へえ?と思って、何かが違ってるのを気づいて、泣きながら本来の問題(創造した問題よりめっちゃ易い)を解きました🥲🥲

創造した問題は大体こんな感じですw

 

F(35分)

めちゃくちゃ私の弱いタイプの問題。円と接線の性質を利用して、角をよく求め、似た三角形を何とか探して、似比を利用してBから接点までの距離、Cから接点までの距離をそれぞれ求めて解けばいいのです。


プール自体を間違えて一度、計算ミスで一度ペナルティを積みました。

 

総評

4eとしては私にはめっちゃ難しかったです。もちろん大部分はBの翻訳ミスとFのせいですが。。。問題をもっと注意深く読んで、特に幾何の問題では図形に気を使って描かなければならないという教訓を得ました。

序盤の問題の難易度も適当で、後半の問題が全般的にとても面白かったので楽しいセットでした。 準備してくださった皆様、心より感謝申し上げます!

競プロの数学問題にアプローチするポイントは?

こんにちは。リユナと申します。競プロでは考えより数学問題が結構出ますよ。今日はこれらをどう接近して解くのか、これらをためにどう勉強したらいいのかについて話そうとします!

 

  • 0.初めに
  • 1.めっちゃ数学の問題を解くためには?
  • 2.数学問題ではなくても、数学的な考え方は役に立つ
  • 3.終えて

0.初めに

続きを読む

数学科出身の競技プログラマーの道: ②私が競プロを勉強した方法

こんにちは。リユナと申します。今日は前の記事から続いて、競プロの勉強法についてちょっとだけ話そうとします!

0. 初めに

こんなことを書く前に、私の履歴を先に少し紹介してこそ説得力が生まれると思います。

ICPC Seoul Regional 2019 13位、2022 7位2023 4位

ーKOI 2017本選 銅賞

ーBOJほぼ2000問題

ーsolved.ac ダイヤモンド1。全体219位

Codeforces max 2224(薄橙)今は滑れちゃってまだ青

AtCoderはまだ水

「自慢できるほどすごい実力者! 」こういうわけではありませんが、それでもそれなりに頑張ってきましたし、自分の考えを書いてみようと思います。Atcoderアルゴリズム黄以上の方々は笑いながら見逃しても構いませんよ。

1. 私は競プロを始めました!

ようこそ!競プロの世界へ!

実はですね。「競プロは初めて!」っていう方々の中でもかなり実力差があると思います。例えばプログラミング自体が初めての方ともうプログラミングには慣れてますが競プロが初めての人はスタートラインが同じだと考えるのは難しいですね。

始める時に意外と引っかかる部分が入出力だと思います。 もちろんプログラミングを学ぶときに一番最初に学ぶ部分ですが、意外と競プロで使われる入力はいろいろあります。 おそらくすでに慣れている方々は、この部分を大きく考えていないので、さらにアドバイスを受けにくい部分でもあると思います。もしこれでなんか問題ができたら、ぜひ!ここからじゃんとして始めましょう!

その次は時間複雑度/空間複雑度の概念についてある程度理解することだと思います。 言語によって、どの言語はどの動作をするのに何秒かかるのか、どのようにコードが制限を超えないのか、そのような感覚がちょっとでも取れていることが重要です。

例えばですね。Nの大きさによってアルゴリズムの時間複雑度はほぼここまでができます。(絶対的なことではないです!)

<10 : O(N!)(全探索などできます。)

<25 : O(2^N)

<100 : O(N^3)

<5,000 : O(N^2)

<500,000 : O(NlogN)、たまにO(NsqrtN)まで

<5,000,000 : O(N)

<10^12 : O(sqrtN)

<10^18 : O(logN)

大体こんな感じです。

あと、言語はC++がおすすめです!私はPythonを中心にしていますが、長所と同じくらい様々な短所(速度など)を持つ言語なので、Pythonを通じて競技プログラミングをするなら、様々な最適化技法や時間をできるだけ減らす方法などについての理解が必須です。

2. 何をすればいいんですか?

自分の意見ですが、競プロに必要な能力は大きく二つだと思います。

1. 実装

2. (アルゴリズムなどの)知識

その二つのバランスを取りながら進むことが大切な部分だと思います。ちなみに、私は実装が弱点です。知識さえも特定の分野に重点を置いていますが、皆さんは私のように偏食しないでください。その為には知識として学んだアルゴリズムや資料構造は、一回でもできる限り自分の力で実装してみる練習をすることが大事だと思います。

2.1. まずは興味があることから!

何をするにせよ、最も重要なことは情熱と興味を失わないことですよ!モチベーションが死んでしまったら競プロをやる理由もなくなるなと思います。(あくまで私自身の意見です。)それをためには、まずは好きなことから始めることをお勧めします!

「あれ?そうやってもいい?偏食じゃない?」って思うかもしれませんが、偏食してもずっとやり続けるのが何もやらないのよりはもっといいです。多くの人は「やってみましょうか」で考えが止まり「やる!」につながることがよくありません。 スタートでもするなら、もう既に上位20%だと思います!

好きなスタイルの問題をたくさん解いてみて、悩んでいるうちに他の要素が混ざっている問題も発見できるようになります!たとえば、私は数学が大好きですが、数学的要素がありますが、他の資料構造(セグ木など)を使って時間の複雑さを減らさなければならない問題に接し、セグ木なども勉強し始めました。 そして漸化式を立てて解く問題は本質的に動的計画法の一種だということを後で知り、その部分も勉強し始めました。

2.2. 良問を解いてみましょう!

AOJやBOJなどのOJサイトではあらゆる問題に触れることができます。もちろん、すべての問題を解くことができればいいのですが、単純に多量の問題を解くよりも、考えさせ、良いチップを与える問題に接することが重要だと思います!

私のおすすめはこんなことたちがあります!

AtCoderの過去問

この文をお読みの方なら、おそらく高い確率でAtCoderでのレーティングを狙われると思います。 個人的な考えですが、韓国国内や海外の様々なプログラミング大会などをさまよっていましたが、アトコーダーは中でも確かに問題の質が保障される良いプラットフォームだと思いました。

でも大会は週に一回じゃないですか? では、1週間に1回だけ競プロの練習ができるでしょうか? もちろん違います。 過去の問題を解いてみると本当に役に立つと思います。私はAtCoder Problemsのようなところを愛用しています。

ーUSACO/KOI/JOI/COCIのような色んな国家の情報オリンピックの過去問

このような大会の基本的な特徴としては、少ない数の問題を与え、一人一人が長い間悩みながら解かなければならない問題だということです。自然に出題される問題は単純に難しいだけでなく、色々な方法で考える能力を育てる方だと思います。
また、このような有名大会の問題はインターネットに解説が着実に掲載されていることが多いです。 解説を見ながらどんなテクニックがあるのか、確実に自分のものにすることが大切だと思います。

KOIは韓国の情報オリンピックです。「負うた子より抱いた子」っていうでしょう。私が韓国人なのでKOIを推薦せざるを得ませんでした(笑)もちろん私もJOIの問題もたくさん解きましたから、どうか許してください。

COCIはクロアチアの大会ですが、かなりいいです。こちらの問題も練習に使えばいいなと思います。

codeforcesはどんな感じか試してみる!

世界的に最も多く利用されている競プロサイトはおそらくcodeforcesの方です。 開催時期も不規則で、(韓国/日本標準時基準)夜11時35分という曖昧な時間に大会が開かれ、問題や文章のクオリティもギザギザしていますが、それでも良い問題もたくさんあります。しかし、全部英問ですので、英語の実力がちょっと要ります。もしかしてロシア語が上手いならそっちで説いても構いませんが、多分みんなそれでも英語の方が易いと思います。普通第1外国語が英語ですからね。

(あれ?私は確かに第1外国語が英語で第2外国語が日本語だったのに、なんでAtCoderの問題を全部英語じゃなくて日本語にして解いてる?)

ちなみに、AtCodercodeforcesは問題が若干スタイルが違います。 うーん、言葉で説明するのは難しいですが、どちらも何回か参加してみれば、何を言っているのか理解できることだと思います。(無責任すぎる)

AtCoderCodeforcesの難易度を比べたら大体

Div 3<ABC<Div2<ARC=<Div1<<AGC

のような感じです。

2.3. 分からない場合には解説を!

「ええ?それじゃ実力に役に立つの?」って思うかもしれません。ある程度はその通りです。 しかし、これは「知っている範囲で解ける問題」の時の話であり、「全く知らない資料構造やアルゴリズム、テクニックが必要な問題」なら悩むのは時間の無駄に過ごすことです。

もちろん、10秒で答え見る天才競プロer!とかになろうという意味ではありません。 あなたは多分、知らない場合にも「あ、これどうにかすれば解けると思うが、時間の複雑さの制限にかかる。 これを最適化するにはどうすればいいの?」のような状況であることが多いと思います。 こんな考えに達したのであれば、これの方法を少し考えてみるのもいいでしょう。 実際、多くの場合、そこから出発して時間を徐々に減らしていくことが実際に解釈が正しいからです。

ある程度悩みが終わりました。 あるいは「最初から知らない概念の問題のようだ」と感じたら解説を探してみましょう。そして、何よりもそれを自分の手で実装してみて、自分のものにじゃんと習得すれば最高のシナリオですね。

2.4. 錯覚すんな!あなたはまだ理解してない!

どんな概念がどのように作動するのか知り、それを通じて簡単な問題を少し解いてから「わぁ! 私はもうこれを理解しました! これが出てくる問題はすべて解けるだろう!」と勘違いすることがよくあります。

全然違います。あなたはまだ理解してない、または原理は理解したが実戦で使いにくい状態である確率が高いです。なぜなら意外と簡単な理由です。 皆さんが別々に勉強する時とは違って、実際の大会で問題を解く時は「どのようなアルゴリズムで解かなければならないのか」教えてくれないからです。セグ木を例にとってみましょう。

1. セグ木の概念をどこかで読む。うーん、分かった!

2. どこで使うのかを勉強する。うーん、なるほどね?

3. 実装してみて何個の易いセグ木の問題を解いてみる。うーん。行ける行ける!

4. よっしゃ!もう私はセグ木を理解した!楽しい!

5. 実際の大会にこんな問題が出てくる。あれ?

6. 何もできず沈没.。

7. あとで誰かに「あれセグ木をめちゃくちゃおにゃららしたら解ける!」って聞く。

8. おかしいな。私は確かにセグ木の勉強をしてたのになぜ?

お気づきかと思いますが、実は私の実話を脚色したものです。(笑)多分私じゃなくてもみんな一回はこんな経験があると思います。それは先ほども言ったように当然まずは「それがセグ木を利用する問題だ!」と大会では教えてくれないからです。

しかし、それだけではありません。多分セグ木を初めて習って「あれはセグ木の問題ですよ」って言われてもそれをどう使うのかは一気に理解しにくいです。しかし、もしあなたがこんな問題を(*韓国語です)悩んでみたことがあるなら、もっと答えに接近しやすいとおもいます。簡単にネタばれをすると、セグ木のノードに1つだけ保存するのではなく、各区間の様々な要素(が何かは自分で考えてください。)を保存して、アップデートの時に次の段階に進んでも最大限問題が発生しないようにすることが核心です。

どうですか?応用することはできるでしょうか?

実はですね、私もセグ木のこと、大嫌いです。もし私がお母さんになったら、私の子供には「セグ木のような悪い子とは遊ばないで!」と教育します。(笑)それはなぜかと言ったら実装の難しさもありますが、応用の膨大さがもう一つの大きな原因でしょう。おそらく赤コーダーだとしても、競プロで使われるすべてのセグ木の応用を知っているとは思いません。

あなたが1、2回解いてみた問題、1、2回実装した資料構造だからといって、あなたがすべてを理解するわけではありません。 この点に気をつけながら、いつも初めて学ぶ気持ちで新しい問題を悩んで学べば、はるかに良い成果を得られると思います。

2.5. 数学もはっきり!

結局ですね、競プロにして数学の要素も大きい部分です。動的計画法の漸化式やグラフ理論、幾何や整数論などがあるでしょうね。これらの勉強もせめて競プロで使われるほどは勉強して置いたら役に立ちます。

もちろん、いくら私が数学が好きだとしても、競プロに数学が事実上すべてである問題が出るのがそんなに良いとは思いません。 それならAtCoderではなくOMCに出なければなりません。そして実際の大会でそれほどの問題が出ることもほとんどありません。 しかし、数学的な概念をある程度知っていれば、はるかに簡単に接近ができる問題や時間を減らしたりするなどの問題がかなりあり、これを簡単に解くためには数学の勉強も必須だと思います。例えばこれは私の好きな問題です。(英問です。)数学的な知識と二分探索という競プロのアルゴリズムが合わせて解ける問題です。 数学が必要ですが、プログラミングの存在も一役している問題だと言えますね。 しかし、基礎的な平面幾何学を知らなければ、最初から始めるのが難しいので、結局数学能力もたくさん必要です。

もちろん、この記事の本論はあくまでは競プロですから、数学だけの勉強に夢中するのもあまり良いことではないと思います。 そうするうちに私のようになりますし、数学科に行ってしまう悲劇(?)が起こるかもしれません。

2.6. 達人たちに聞いてみて、ライバルと一緒に成長しよう!

競プロのコミュニティには数多くの達人たちがいらっしゃいます。おそらくその中にはこの文を書いている私よりずっと実力者の方も多いと思います。そんな方々がどのように勉強してきたのか、どんな問題を解いたのかをそばで見守るのも勉強に大きく役立ちます。 また、本当にわからないことがあったら聞いていただければ、快く答えてくれると思います。 何よりもその「解けた!」の楽しさを共有したい人が多いですから。

もちろん、相手は無償で好意を寄せていることは覚えておくべきです。 手伝うことが絶対義務ではないですし、助けてもらったなら感謝の挨拶もしっかりした方がいいと思います。

そして、自分がどんな実力であれ、似たような実力の人々にも出会うことができます。 善意の競争をするライバルがいれば、自分と相手の両方がシナジー効果によって大きな成長を収めることができます。 もちろん勝負に執着しすぎるのは自重しなければなりませんが。(そうでなければ私のように大学卒業さえ延々と先送りする競プロ悪鬼になります。)

3. 終えて

あなたが競プロをしようとする理由はさまざまでしょう。私のように単純に興味や競争心のためかもしれませんし、就活の準備やプログラミングの実力を伸ばすためにもするかもしれません。しかし、その理由がどうであれ、長く悩んでいた問題をやっと解いた時の「解けた!」という喜びは同じだとと思います。

まあ、「競プロ無用論」や「早くやめとくほうがいいな」っていうことも、前にも言ったように両国のコミュニティでたくさん聞ける言葉ですが、結果がどうであれ、あなたが一歩ずつ前に進むために悩んだ時間は嘘ではないと思います。そのように情熱を注いだ経験がこれからの競プロや、じゃなければ他のどの分野でも、少しでも役に立つのではないかと私は思います!その道の上に立っているみんなを心から応援します!

読んでくださってありがとうございます!

数学科出身の競技プログラマーの道: ①始まりから今までの軌跡

こんにちは。リユナと申します。今日は簡単に、私が競技プログラミングを勉強し始めたきっかけについてご紹介したいと思います!

 

 

0. 概要

皆さんはどうやって競技プログラミングを始めましたんですか?その時の記憶はありますか?私はあります。

いつも言ってますが、実は私は数学科です。まあ電算学科も複数専攻してますが、基本的に私が考えることや問題を解くために接近する方式などは工学者よりは数学者のような考え方により近いと思います。私は、私が記憶できる限り最も遠い過去からずっと数学が好きでした。なぜかは今も分かりませんが、数学を勉強すると自然に「これは本当美しいな」って思うことが今も結構多いです。いわば天性から数学科だったと思います。

そんな私だけど、競技プログラミングは本当に大好きです。いや、実は「競技プログラミングに関連のない他の電算学の分野」に関心がないと言った方が正しいかもしれませんね。私は徹底的に「私が好きで興味を持っていることに集中する」スタイルなので、もし興味がなかったらここまで来ることもなかったでしょう。今日は私が競プロを始めた理由、好きになった理由、そして勉強してきた方法について少しずつ説明する淡々とした雰囲気の文章を書いてみようと思います。

実は勉強方法だけを書く記事を書こうとしましたが、前の部分の内容があまりにも長くなったので、記事を二つに分けて書くつもりです。 この記事の次に勉強法について書く予定です!

 

1. 始まり

私は「韓国科学技術院敷設韓国科学英才学校」という、どこかの漫画やアニメに出てきそうなとんでもない名前の高校を出ました。まあ実はそれでも、私の口では言うにはちょっと恥ずかしいですが、韓国の最難関高校の一つだと思います。韓国にも偏差値があったら多分75は軽く超えるでしょう。日本でいうと、全校生の80%が東大、京大、あるいは東工大に行くと言ったら一通り説明になると思います。

「まあ、それですごいことはわかるけど、それがどうしたの?」って思うはずですね。実は高校でプログラミングが一年生から必須科目であって、それでプログラミングに初めて接したからです。それまでは一度もプログラミングをしたことがなかったので、一つ一つprint("Hello, world!")を入力した記憶が今でも生々しいですね。ここで気づいた方も結構いらっしゃると思いますが、最初に習った言語がPythonでした。確かに直観的で学びやすかったのはよかったですね。でも競プロには弱いところがたくさんあります。これについては多分後にかく勉強方式の記事でもっと説明する予定です。

プログラムが私の意図に従って機能し、動くのが不思議で楽しかったです。 それを通じて様々な問題を解くことができました。当時はこれが試験勉強でしたが、私はむしろとても楽しかった記憶が大きいです。でも、「それ面白かったよ~」くらいに移って、その後またプログラミングをしなかったのかもしれません。

もっと本格的なきっかけは高校2年生が終わる頃にできました。 1年上の親しい先輩が競技プログラミングを当時着実にしてきて、私にも勧めました。 授業時間に簡単に学んだアルゴリズムを利用して数多くの問題を解いて、それを悩み、インターネットサイトに提出して自分の解釈が正しいかどうかを確認できるという点が本当に不思議でした。その時からBOJを始めて、ACの喜びを感じ始めました。

気が付いたら、高校3年生の時には大学入試を控えていたにもかかわらず、一日中パソコンの前に座って、BOJで問題を一生懸命解いていました。 この頃KOIの存在を初めて知ったので、遅すぎたけど、それでも一度は挑戦してみよう。 ということで、最終本選で銅賞をもらった記憶があります。

しかし当時の私の勉強方式は良く言えば「熱心に」で、悪く言えば「何も知らずにむやみに解いた」に近いでしょう。 高校3年生を卒業するまでセグ木が何なのかさえ知りませんでしたからね。当時にはsolved.acのような事もなかったし、codeforcesAtcoderの存在も知らなかったので勉強方式がめちゃくちゃでした。しかし、この時の経験は私が基本技を徹底的に固めるのに役立ち、知っている問題であれ知らない問題であれ、問題一つ一つに真剣に取り組む態度を学ぶきっかけになりました。何より、「競プロの面白さ」をしっかり学んだ時期だったので、私にとっては今でも大切な記憶です。

 

2. 大学を入学してから

もちろん当然学校の勉強や大学入試も充実してきたので、無難にKAISTに入学することができました。1年生の時に初めてICPCの存在を知り、競技プログラミング研究会で何とか誰でも捕まえてチームを作って予選に参加しました。 しかし、当時は経験があまりにも足りなかったし、実力も足りなかったので予選で凄惨に失敗して落ちましたね。でも初めてのチーム大会だったので、いい経験になりました。

この時に研究会に入ってから色んな人々と出会いました。IOIの韓国国家代表出身のやICPC WF出場経験のある人たちが並んでいて、私はその間で人々がどのように勉強してきて、何をしてきたのかを着実に追ってきました。今でもずっと感じることですが、同じ趣味を楽しむ人たちがそばにいるということは本当に大きなモチベーになると思います。

そして、この時に本当に韓国の競技プログラミング界に革新的なことが起こりました。 solved.ac がベータサービスを開始したのです。以前までめちゃくちゃに、よく分からない状態で何でも挑戦してきた私には本当に新鮮な衝撃であり、分類タグで知ることさえできなかった数多くのアルゴリズムと最適化技法を一つずつ見ながらネットを探しながら勉強しました。あと人々のティアが出てくるのも、負けず嫌い私には大きな動機付けになりました。 難しい問題をどんどん挑戦して解いてみるのがとても楽しくなりました。solved.ac がリリースされて以来、韓国の競プロerたちの実力が上向き平準化されたという話がよく聞かれますが、私は実際に多くの恩恵を受けたと思います。

二年生になってからはBOJで様々な問題を解いて、時間が合えばcodeforcesで大会を行うという形で、その前までとは違ってとても真剣に競技プログラミングの勉強を始めました。そうしながら、私の強みを確実に把握することができました。 私は基本的に数学科でしたし、大学1年生の時にすでに「韓国大学生数学競技大会」で金賞をもらうほど問題を解く実力はかなり優れていました。競プロをしながら数学的要素が入っている問題は、私が他の人に比べて優位を持って問題観察ができるという点を把握し、多分このような部分が「私にも上手くできる部分があるんだ!」と大きく動機づけされました。

また、ICPCチームを決めながらも大きな幸運が伴いました。 当時、校内上位チームの一つで規定上の問題で一人がやむを得ず抜けることになり、急いで代替人員を探さなければなりませんでした。 ところで、そのチームのメンバーの一人が上で話していた親しい学校の先輩でした! おかげで私はそのチームで数学担当を務めることができ、立派なチーム員と共にしながら実力者たちはどのように勉強して練習するのかを確実に学ぶことができました。当時はソウルRegionalで13位を獲得し、奨励賞を受賞しました。

率直に言うと、当時の私はそのチームにいるにはあまりにも実力が落ちる状態でした。 過分なほど良い機会ができて実力者たちの世界を一度味わった気分? そうだったからますます大きな目標ができて、私もその場に合う、どこかで「あたし、こう見えてもICPCの賞ももらったよ」と言うので恥ずかしくない人になるためにもっと勉強し始めました。

 

3. 休学

その途中で私に他の方に機会ができてしばらく休学をして某会社でプログラマーとしてインターン生活を体験することになりました。どうせコロナウィルスのせいで学校で正常な学生生活を送ることができないと判断されるので、この機会にいっそ他のことをしよう!とも思いました。 ちょっとだけ指摘しますと、韓国では日本と違って大学生の休学が一般的です。 最大の原因はもちろん兵役の問題であり、そのため休学自体が一般的なものと認識され兵役がかかっていなかったり、すでに解決している人たちもリフレッシュや就活、創業、その他の体験や勉強などのために休学することがかなりあります。ケースバイケースですが、少なくとも私の学校はもっとそうでしたね。

まあ、その経験については詳しく書かないと思います。多分これからも話すことはないと思います。だって、当時の私は社会に出る準備ができていなかったし、たくさんのつらいことがあって心と体の健康をかなり台無しにしました。

それで会社生活を終えても回復のためにある程度休んでから学校に復学することにしました。 まあ、それが私が年が多いのにまだ卒業してない理由にもなります。当時の私は本当に何もしないで家に横になっていてもいい状況でしたが、勉強するルーチンを蘇らせ、復学後の学校生活に備えるために競プロの練習に再び没頭しました。

当時の私はどうせ残るのが時間だったので、できるだけ色々なアルゴリズムを勉強して、どんな状況で使うのかを見るためにたくさんの問題を見て、直接実装してみたりして勉強を重ねました。 これを続ければ続けるほど、solved.ac でティアがどんどん上がって達成感が高くなりました。 codeforcesもまた始まって、当時薄橙まで上がっていましたね。(今は大会を何回か台無しにしてまた青ですよ)

実際、この時勉強したアルゴリズムの中で、今も実戦で上手に使えるほど慣れているものはそれほど多くありません。 特にチーム大会だと、いつも私よりはコードの実装が上手なチームメンバーがいたので、私がコードを書くことはそれほど多くありませんでした。しかし、私はこの期間、「どのような類型の問題でどのような方向の解釈を取っていくのか」に対する大まかな感覚を知り、「少なくとも私が確実にできることは逃さない方法」を学んだと思います。 これは、特にチーム大会で問題の解き方を話し合って進むのに大いに役立ちました。

まあそんなにだんだん時間は流れ、私はまた復学するようになりました。

 

4. 復学後から今まで

復学の頃に私は友人から「私の母校で競プロがとても上手な2人の1年生がKAISTに進学するが、ICPCチームを作る残りの1人を探している。 あなたは数学に特に強いので、もしよかったら紹介してもらえない?」という提案をいただきました。私には本当に千軍万馬のような存在で、その後の成長に大きく役立った友達に出会いました。

これがMunSongSongチームの始まりでした。

二人の後輩たちは素直に言って、競技プログラミング自体の実力は私よりはるかに優れていました。 私も休学期間中に能力を磨いて足りない水準ではなかったですが、高校の間KOIとIOIの準備をたくさんしてきた後輩たちに比べものになりませんでした。 ただ、以前まで勉強をしてきたことがあったので、私は二人が話す内容自体はかなりついてくることができました。

チーム練習を重ねながらICPCのための準備をしてきましたし、お互いがお互いの長所と短所を明確に把握しながら大会への戦略を立てていくことができました。 これについての話は以前書いたICPCのレビューでもしましたので、今は省略したいと思います。まあそれで、2022年ICPCでは7位で銅賞、そして2023年ICPCでは4位で銀賞を受賞するという素晴らしい成果を上げました。 今は本当にWF出場以外、すべてのことをやってみましたね。ただそのせいで私は今すごい競プロ悪鬼になって卒業すらできなくなりました。ww

この期間にもう一つ説明することといえば、私が高校の時から教えてきた後輩たちがいます。私は高校3年生の時、当時1年生の後輩として初めて入ってきた学生たちを対象にプログラミング科目の補充講義をしました。 最初はみんな1年生の時の私のようにプログラミングに初めて接していましたが、彼らの実力はすぐに日進月歩きました。 学期が終わる頃には、私がいたずらで出したKOI問題をBFSを習ったこともないのに、自分で考えて解くほどでしたよ。 私はこの後輩たちと早く仲良くなれたし、弟子(?)にして競技プログラミングを教えながら親しくしてきました。

彼らが奇跡的に全部入試にも成功して、みんなKAISTに来ました。まあ実は入学はもっと前でしたが、コロナウィルスのせいで、あと私は休学してたから学校で会えませんでしたね。私は親しい後輩たちと大学でまた会えて本当に嬉しかったし、また一緒に競プロを一生懸命勉強しました。 高校生の時の私とは比べ物にならないほど私も実力が伸びていたので、私ももっと体系的なカリキュラムで徹底的に教えることができました。 いつの間にかその後輩たちは私にとって数学がそうだったように、自分たちが好きな分野を一つずつ探してその部分を自ら勉強し始めました。 今では、それらの分野に関しては、私よりもはるかに優れた実力を持つ素晴らしい競プロerになりました。

そして今になっては、本当に偶然のきっかけによって日本の競プロerたちともつながるようになって、もっと多くの人たちと交流したくてこのように日本語で記事を書いていますね。 他の国の学生たちがどのように勉強し、悩みながら競プロをするかを学ぶ機会は本当に貴重だと思うので、私はこれもまた私にとって大きな転換点になったと思います。そして私も、皆さんにできるだけ私が経験してきた話をしたいです!

 

5. 終えて

実は私が競プロをしてきた経験、その過程で会った人々、してきた悩みに対する話はここに全部込めないほどはるかに深いです。まあ、誰もが自分だけの素敵な話を持っているものですから。私も私のすべての経験を伝えることができなくても、これを通じて少しでも競プロを楽しむ一人がどんな感じで今までやってきたのかを知ることができれば、私としてはこの上なく嬉しいと思います。

結局、私が競プロを長い間楽しんできた原動力は、「知らないことを知った時の喜び」、「だんだん実力が上がっていくのが感じられる時の達成感」、「負けず嫌いの競争心」、そして何よりも「好きなことを一緒に分かち合い競争しながら助け合える人たち」がいるからだと思います。「競プロ無用論」や「早くやめとくほうがいいな」っていうことも競プロのコミュニティなら両国共通でよく出てくる話ですね。だけど、私にとってはこれは楽しい余興や趣味のような感じで、ある意味ゲームのような存在だと思います。皆が考えるところはそれぞれ違うでしょうし、私の意見に同意しない方も本当に多いと思いますが、まあ、すべての人が楽しむ方法はそれぞれですからね。

少なくとも私は、私がこれをしながら感じる楽しさが減り、疲れだけが大きくなるという気がするまでは、大会に出られるかどうか、それが実際に学問やプログラマーとしての活動に役に立つかどうか、地道に少しずつ競プロをしていくと思います。そして、私の達成感ややりがいを、誰かと少しずつ分かち合えたら、それもまたとても嬉しいと思います!

次の記事では、私の話よりは、もう少し具体的に私が考える競プロの勉強法について説明します。 読んでくださってありがとうございます!