第一回日本最強プログラマー学生選手権-予選-

コンテスト前36.4、コンテスト中36.7と、いい感じの体温。C問題のバグがわからなかったのは残念だが、久しぶりに普通のコンテストができた。

A - Takahashi Calendar

問題文が表示されるまでに45秒くらいかかった。難しそうな見た目のくせに書くだけ。

B - Kleene Inversion

300点で転倒数とはたまげたなあ(企業コンではよくある)。まあ簡単そうだというのはわかる。K個の領域に分けて考えると、同じ領域内での転倒数は普通の転倒数のK倍、違う領域のは自分より小さい数の個数のK*(K-1)/2倍。Nが小さいのでO(N^2)でいい。

C - Cell Inversion

マスを2つ選ぶとき、右側になるマス(Rとする)と左側になるマス(Lとする)に分ける。すると、全体を反転し、左端からRまで反転し、右端からLまで反転したのと同じ。全体を反転する回数はN回、Nが奇数なら最初に全体を反転させればいいか。左端からのと右端からのがN個ずつあるのでかなり複雑。長さがsと同じtを作りLRからなる文字を入れることにして、RLという並びはペアにして全体をカバーできる。RLを除くとLLLRRRみたいになるのでまだ考えられそう。ただ、逆向きに構成するの大変そうで、ここらで進みが遅くなる。21:40くらいまで考えてDへ。

ていうかsの隣り合う色が同じならtの隣り合うものは異なる、違うなら同じになるように設定するしかないのでは。あとは、その時点で一番左のRの相手のLが何個あるかを掛け算していけばいい。途中でLが足りなくなったらダメ。最終的にLとRの数が同じじゃなかったらダメ。あと、左端はLなので左端の反転は1回、つまりs[0]=='B'も条件(前半に考えたこと全然関係ねえ)。Nの階乗を忘れていたので掛けるとサンプルが合うので提出、WA。以降、間違っている箇所の心当たりが全くないまま終わった。Eが読めなかったのが残念。

D - Classified

N=4の例で考える。別に戻るパスがなくても条件満たすよね、AtCoderにしては珍しくそこの注記がないけど、とか思ってたけど今考えたら部屋につながってる辺を往復するだけで戻れたわ。しばらくして二部グラフを思いつく。どうやら必要十分条件になっていそう。奇閉路があったらダメだし二部グラフなら偶数になる(これも今考えると「奇閉路がない」でそのまま同値だ(というか二部グラフに「偶閉路しかない」という言い換えがあるの気づかない))。辺集合をいくつかに分けるイメージ。すると、頂点集合をできるだけ個数の差が小さい2つに分けていく構成方法が思い浮かぶ。より小さい問題に帰着されているから再帰で書けそう。解法の妥当性だが、親のレベルはもう使えないからまあ小さい問題に帰着されてるし、そうなると最初に分けるのもこの分け方よりいいものはない。厳密ではないがよさそうなので実装に入る。i0からi1までを2つに分けてレベルdの通路を設定する関数を書く。頂点数が2未満になったら何もする必要がない。i<jとなるa[i][j]を出力するので、配列に書き込むときもi<jとなるよう気をつける。