ABC130

開始前36.6、Fを通した後36.8。わりと体温も理想的では?いや上がるのが正常か知らんけど。昨日と違っていつもの感じで参加できたのでよかった。準備をちょっと忘れたりしたがまあ適当に過ごしてた日のほうがいいよね。Dでグダったのは仕方ないけど、流れは4完遅解き(見切り提出に成功したので遅くもないと思うが順位表で見るとけっこう遅い)だった。そうなってしまうこともある。でも調子がいいときは何か起こることが多いもので、Fに注力して通すことができた。嬉しかった。松本「生きててよかった…!」。

A - Rounding

問題文の通りに実装する。状況が一目ではわからないので、問題文を見ながらでないと実装できない。

B - Bounding

跳ねる高さが関係ないんだよね。この問題文は相当読みづらい。1回目はX以下なので、2回目からのN回ぶんをカウントする。問題文が読めれば、いい問題。

C - Rectangle Cutting

こういう問題もっと出題されてほしい。紙の上で色々試すと、中心を通る直線を選ぶことで最大を達成できることに気づく。誤差が許されることにニヤニヤする。さて、(x, y)が中心なら簡単だが、そうでないときに一通りしかないことが証明できない。色々なケースを手で試し、順位表もペナルティが多発してないか一応見て提出(バッドノウハウっぽい)。(解説PDFを見て)中心を通らない場合、通るように回転させれば面積が変化するから、中心を通る一通りしかないですね。こういうのをコンテスト中にちゃんと証明できないのは本当に弱すぎる。毎週コンテストに出て何やってんだ。

D - Enough Array

ド典型しゃくとりじゃんと思ったが、しゃくとりで列挙された区間より短い(K未満のほうを数えて引き算)ものもOKでそれをカウントするというのがひねり。普通に実装したつもりが、サンプル通るものは範囲外アクセスを防げてないように見えるし、自然な感じにコードを直すと落ちたり(ローカルPCでのRE)するので何もわからなくなった。そもそも俺はしゃくとりを書けるようになっていたはずでは?いくら考えてもソースコードの正しさや誤りがわからないので、通りそうなのを提出した。AC。ACとは運の良さである。ここは復習しないとな。実装が理不尽に重い問題はイヤだが、この問題は簡単に書けるはずだと感覚でわかるので復習しがいがある。

E - Common Subsequence

あまり時間をかけていないが、それにしても全然わからなかった。Fを解いているときに間違えてこちらを見て制約の2*10^3に気づいた。O(N*M)を考えると、編集距離的なDPがありそうな形だなと思う。そう思って考えてもわからず。部分列の組のうち整数列として等しいもの。状況が想像しづらい。

F - Minimum Bounding Box

EよりFのほうが解けそうなのでずっとこちらをやっていた。実行時間制限5秒が怖いが。碁石を手で動かして考える。縦と横で片方が増えて片方が減るときを考えると、寄与が大きいのは小さいほうだ(速度は一定なので小さいほうが倍率が大きい)。つまり、小さいほうを減り続けるかぎり移動させ続けたときが答えだ。下端にあるものが全部上に動いていたら減っていて、どこで出会うか。難しそう。いやO(N)を何回も何回もやる二分探索か!なら5秒なのもわかるか?移動方向が異なる2点のx座標が一致するのは0.5の倍数時刻のみ(整数で扱えそう)。とりあえず4方向に分けて1方向だけを考える。減って平らになって増えるという遷移。上下を合わせると-2,-1,0,1,2。と思ったが、境目だけを考えればいいので単に1方向の-1,0,1の2回の変化点だけを知ればいいか。最大値の時間経過による挙動パートとそれをどう使うかのパートがあって両方を気にしながら考察を進めていったが、できそうな見通しが立った。

点をstructにして初期位置と速度を4変数で表す。入力を2倍して受け取り1/4倍して出力すればいいのでそうする(全部整数になるしオーバーフローも大丈夫)。時刻tの指定方向の最大値(-最小値)を返す関数を書く(4通りの向きによってx,-x,y,-yを使う)。あとは三分探索(1秒後までの変化量で二分探索)で切り替わり地点を4方向*2個求めて時刻0を足して9通りを全部試すだけ。ドキドキのサンプルチェックだが、サンプル3だけ負の数が出力される。つまり、おおむね合ってそう。デバッグすると、二分探索で範囲内に答えがなかったときの処理だった。チェックすべき時刻が存在しなかったということなので、そういう値はスキップすればいい(時刻0を追加してあるので9個全てがスキップされることはない)。かなりすっきりしたコードになったのが嬉しい(ていうか、だから40分でACとれたんだよな)。