AtCoderのコンテストに出る前の準備

あまり儀式が多くなるのは嫌だが。

  • 夕食は食べすぎない(もちろん十分に食べる)
  • 風呂はコンテスト前に入るなら早めに
  • 早く寝たいなら、歯磨きなど寝る準備をしておく
  • 水を飲むなら30分前くらいに(直前だと便意がくるかも)
  • トイレに行っておく
  • 考察用のノートと鉛筆を用意する
  • 開発環境を立ち上げリビルドかける(初回は遅かったりする)
  • 参加登録を済ませておく(特に企業コンは時間がかかることがある)
  • 問題のURLを順位表から開いておく(時間になったらF5)
  • 耳栓をする(気に障る小さな音に効果的)
  • 深呼吸する(考察用酸素)
  • ラムネを用意する(1時間以上考え続けるための糖分補給)

ABC129

開始前36.7(風呂が熱かったせいか?)、Eを通したあと37.1、終了直前36.7。体調悪いから上がりやすかったかも?ただ、コンテスト体験としてはよかった。力も出せたと感じている。始まる前から耳栓をしていたのがいいムーブだった。

A - Airplane

珍しく30秒くらい読み込めなかった。最大のやつを使わない。考察は面白いけど、ループを使えないのがストレス(使ってもいいけど実装は遅くなるだろうし)。maxをmax({p,q,r})の形で書くのを思い出すのが微妙に遅れてもにょった(ちょうど解説にあるようなコードを書きたかった)。

B - Balance

これなー、片方を0個にしちゃいけないという問題で、それをちゃんと書くのに苦労した。でも、今気づいたけど片方を0個にするより1個とN-1個にしたほうがいいから気にしなくてよかったんだ。酷い。最小値をとる初期値も、1<<30にしたけどs(予め計算しておいたΣw)でよかったしほんと酷いな。

C - Typical Stairs

あまりにも典型なDP。あとで、メモリ使用量を減らしたのも書きたい(さすがに、実装スピード優先にしました)。

D - Lamp

解法はすぐわかったけど、4通り書かない実装が思い浮かばず。reverseとswap(s[i][j], s[j][i])で4通りというのも考えて実装しかけたが、照らされるマスの数を格納する配列にもこの操作が必要なのに気づいてやめた(追記:その時点ではやめてなくて、h!=wのケースに気づいてやめたんだった)。結局コピペで4つ。照らすマスの数の0初期化する位置を間違えてて、4回直した。だから嫌だったんだよ。こういう実装はやりたくない。

E - Sum Equals Xor

あとから考えるとこれもすごく典型だな。上の桁から見ていって、10000未満・10100未満・10101未満・10101と考える(最初に1を足すことも考えたけど桁数変わり得るしそこでバグらせてもあれなので見送った)。10000未満の場合だと、aとbのビットが立ってる位置が被ってちゃいけないから、aに立ってるかbに立ってるかどちらにも立ってないかの3通り。2つの条件があるが、逆の順で見たほうが考えやすい。4桁なので3^4通りとなる。10000以上10100未満のときは、上位のビットは確定しているので、そのうち1のものがaに立ってるかbに立ってるかの2通り。2^1*3^2通りとなる。最後に10101の2^3通りを足す。Lに1を足して検算したいなあと思ったけど時間もないし提出。

F - Takahashi's Basics in Education and Learning

一応問題文を「素数」で検索する(Mが素数とは限らないようだ)。Lがクソでかい(L回ループはできない)。桁数は高々18なので桁数が増える回数も高々18回。つまり、桁数が変化しない問題が解ければいい。102105108111みたいなのは111+108000+105000000+102000000000になる。まあ1000倍して引いてやれば(等比数列の和を求めるときみたいに)できそうだよね。頑張って計算するが、Mは素数じゃない。割り算したいのだけど、あまりがそれになるやつが複数あるかも。これに気づいたのが終了15分前で、これは解けないと思った。なんかextgcdみたいにしてできるのかなとか思ったけどそれも無理そうだよなあ。これは力不足。(解説をちょっと読んで)いやあ、なるほどだけど、解説をから目を離して考察が自動で進むわけでもないので、力不足。教育的な問題多いっすね。

AGC034

Bを通して37.0、Cを通して36.8。BをACして順位表を見ると意外と低い順位だったが、それでも気分はよかった。B問題がすごくよかったから。

A - Kenken Race

要するに連続した石がなければいい。Bの人(ふぬけ君)が先に動けば干渉することもない。その辺をじっくり抜けがないか考えて、5分くらいしてC>Dを考える問題だと気づく(遅いよ)。追い抜くためには、3マス連続したスペースが必要。それもじっくり考えて、やや不安はあったが提出してAC。考察内容のわりにACしてる人が少ないのも不安だった。ちゃんと証明できればそんなの関係ないのだが。

B - ABC

これ好き。問題を目にした瞬間嬉しい。色々考えて、解けそうな(自分に解けるという意味ではない)問題だとは思えたものの、かなり曖昧な考え方しかできていなかったが、BCを塊として捉えることに気づいて見通しが立った。BCが左へ沈んでいくと思えば、AとBC以外で切りつつ左のAの数を持って足していくことで答えが求まる。解けてる人多くて、天才以外お断りコンテストは実際に天才ばかり出ていると思った。

C - Tests

X点まで上げたときの効率がいい順にX点とって残りをどれかで取るという最も普通っぽい解法に行くまでにかなり時間がかかった。思いつかないとかじゃなく順調に進んでて。さて、X点取るにはX時間勉強する必要があり、時間が一定なのでイメージより簡単。点数が高くなるほど効率がよくなるので、X点を取らないものが複数あると風船みたいに片方へ全部行きそう(つまり一つしかなさそう)。まあ行けそうなのでサンプルで様子を見るが、通らない。サンプルすら通らないというのはわりと想定外。変なケースを置いててくれたということで、考える(サンプルが複雑なので正解を自分で計算することはできない)。半端を処理する部分のコストを優先することはありそうだと思いつく。計算量が爆発しそうだが、半端をO(N)通り試して、残りは大きい順に全部なのが明らかだから、O(N)で行ける。実装するが、やはりサンプルは通らない。単純ミスを疑い、不等号が逆なのを発見する。この単純ミスがなければサンプルは最初から通っていたのだ!これは運がよかった。単純ミスを考察漏れと勘違いして漏れを発見できた。そしてAC。これは嬉しかった(ガッツポーズした)。

漏れは発見したが、他の漏れがないという確信はなかった。そもそも、残り30分で「普通の貪欲みたいなので時間をかけて書いたのでとりあえず提出してみるか」みたいな感じだった。運良く漏れを発見したので行ける可能性も高いと思っていたが。想定解は二分探索で、X点とる個数がわかっているというのが明快だ。自分の解法は、まず貪欲にX点をとっていくことでとりあえずの答え(真の答えはこれと同じかより小さい)が求まる(半端は全探索)。ここでX点をk個とったとすると、k個以下なのは確定。k-1個+半端だとすると大きい順にk個をとるより劣るので、k個。正しいのでは?よくわからん。そもそもコンテスト中はなんも証明してなかった。半端の位置を決めればあとは大きい順にとるだけという問題だった。半端の位置を先に決める。そのときに、X点とるのを何個にするかは確かに定まらないか。

M-SOLUTIONS Programming Contest

開始前36.4、Dを通して測ったら36.5。集中力がない(だから短時間のコンテストが好き(最近は長いほうが得意な気がしてるけど))。ぷよぷよをやるときも、試合に全力を注ぐために短期決戦の速攻を仕掛けたりしてる。今回でいうと、難しそうなEは諦めたほうがいいかもしれないが、集中するため、貴重なコンテストの時間を捌くため、面白そうなEも考えていた(実際は、2問並列に考えるのはパフォーマンスの期待値を下げないと思うけど(じゃあ絶対そうするやん?(だからそうした)))。

いい問題だったよ。レーティングも上がった。しかしなんでこんな気持ちに。

A - Sum of Interior Angles

最初、(n+2)*180って書いてサンプル合わないのでマイナスに直した。

B - Sumo

サンプル2が親切。8勝するためには8敗しないことが必要。最初、可能性がないときにYESを出力するようにしてしまった。

C - Best-of-(2n-1)

問題文が明快でいいね。そして解法を考えると昨日考えてた「ぷよぷよの30先が勝率p側の30-kで終わる確率」がもろに使えそうじゃん!実装に手間取りながら書き進めるが、引き分けが思ったより大変そうだと気づく。さすがにひねりが利いてるなあと思いつつ。「実は引き分けの処理は簡単そう」「引き分けを加えて正面から解きなおす」この2つで迷う。前者で行けそうな雰囲気は感じるが、後者で行くのが無難な気もする。結局前者で行けた。まあN+i試合で終わるケースの確率がわかってるので、そこに引き分けを混ぜる感じで。何で割って何を掛けるかでけっこう混乱して、そもそもA/100ではなくA/(A+B)で計算するのをわかってなかった。これもサンプルがかなり親切。入力が0のケースと入力がでかいケースがちゃんとある。

D - Maximum Sum of Minimum

貪欲ではさすがにダメっぽいが。けっこうたくさん解かれている。最大化するってことは何かを最小化する?N個の数がN-1回現れる。小さいほうから見て行けそう。しかし、貪欲じゃダメだが貪欲じゃないなら解けないだろ。このときは、小さい順に葉に書き込み頂点を削除するのを繰り返すのしか思いつかなくてそれは反例があると思っていた(しかしこれ反例ないか)。反例を作るという方向性はずっと頭にあったが、何も見えずに計算することができないんだよね。「あっ、こっちへ行ったら解けそうだな」という感覚が少しでもないと手を動かすことすらできない。最大を達成するのがどのくらいきつい条件かイメージできなくて。もう何も見えなかった。

最大のcが辺に書かれることはないとわかっていたので、合計は小さい順にN-1個足したもの以下にしかならない(ほんとに自明か?)。で、DFSすればそれを達成できる。はー。無の考察がつらかった。

E - Product of Arithmetic Progression

dが毎回違うのがつらすぎる。なんか規則性はありそうだけど、たとえば1,4,7,10,13...の積とか無理でしょ。事前計算はせいぜい100万の100倍まで。クエリも10^5あるから1000回まで。絶対面白いと思ったが、結局は何もできなかった。