ABC305

6完。これでこの順位なのきっつ。Cで珍しくWAを出した。やっぱ競プロ漬けの生活してないとスピード落ちるのかもなあ(「漬け」なことあったか?と自分では思うけど、コンテストに出て最低限の復習以外何もしてない現状よりはずっとしていた時期もありそう)。

A - Water Station

最も近い5の倍数を求める。5が奇数なので一意に定まる。あまりを求めて3未満なら引くだけ、そうでなければ引いてから5を足す。-=の中で5を足す向き間違って時間かかった。

解説、roundはすげえ。2を足すのはかなり難しい。

B - ABCDEFG

円周率になっているので入力しやすい。最初に0を追加して累積和。点は7個だがその間は6個で、Aから各点までの距離を求めておく。swapとabsで迷ったが、swapにした(複数の方法を思いついて迷うところまで行ったのはいいことだ)。

まず4つの角の注目した。そのうち少なくとも3つは残っている。そのための「縦横 2 マス以上」か。チーズが存在する長方形のbound(でいいのか?)を求めればいい。最大値と最小値を合計4つも求めるのめんどくさそうと思って、最初に見つけたのが最小値で最後に見つけたのが最大値という方法を思い出して使った。

WAで、まあ縦には順番に見てるけど横方向は行ったり来たりしてるからね(マジでなんも考えてないんだな)。横だけループ順序を入れ替えたので求めて提出してAC。これACはしてるけど、提出した時点でははっきりわかってない。もやもやしてるけどさすがにこれで通るだろくらい。これはしょうがないんだよなあ。コンテスト中にしっかり考える時間はない。面白いことを見つけても、コンテスト後までおあずけにしないといけない。コンテスト時間は本当に短い。

Cまで、面白い問題ばかりでよかった。Dからが面白くなかったという意味ではなく、D以降はいつも大体面白い。

D - Sleep Log

睡眠時間の累積和を持ちたいが、与えられるのが時間の累積和なのでやや混乱した。具体的な求め方は、それまでの非睡眠時間を更新しながら引いていく。時間の累積和をA、睡眠時間の累積和をBとする。Aでlower_boundして求めたインデックスとBから睡眠時間の概算ができる。あとは、誤差の部分が寝てる時間なら補正する。

あー、lまでの睡眠時間とrまでの睡眠時間がわかればいいんだから同じ問題を2回やるだけだ。補正をlとr別々に考えてたアホか。

平方分割も考えたくなるようなやばさ。いや落ち着け多点スタートのBFSのようにできないか?警備員は、体力が1小さい警備員を隣の頂点に配置する能力を持つとしてもよさそう。体力が1以上なのが嫌らしいね。制約が0以上だと思って解くことにする(より難しい問題を解くほうが見通しがいい場合もある)。体力が高い順にソートして、いいタイミングで合流させる、難しそう。どうせソートでlogが付くなら最初からpriority_queueを使ってダイクストラ風にやればいいのではないか。頂点に体力を割り当てる。体力の高い順に処理する。隣の頂点の体力をより高く更新できるならしてキューに入れる。BFSを考えればわかるように、各頂点について1回しか処理しないので、計算量は大丈夫。キューからは、更新されて役に立たないものも出てくるので、体力が実際の値より小さいものが出てきたらスルーする(これはダイクストラ法と同じ)。

まあ解けるけど当然時間はかかる。これをこの人数通してるのやばいなあ。

(追記)スタート地点を別に用意して警備員へ辺を張るのなるほどなあ。そういう構造をしていたのか。めちゃくちゃ見通しがよくなる。イメージはBFSだから抵抗あるけどやってることは同じだ。

F - Dungeon Explore

インタラクティブと聞くとやりたくなる。アダプティブってAtCoderでは初めてじゃないか?またBFSかと思って考えていくが、隣の頂点へしか移動できないのがつらい。ああ、なんで2*Nという制約なのかと思っていたが、DFSか。実装がけっこう難しいというか面白くて、再帰のDFSを書く。いやシーケンシャルなやり取りをしてるのに再帰って。戻るときは空読みをする。手でサンプルと小さいうにを試してデバッグ(変数名間違えてたり、戻るとき移動先を出力してなかったりしてた)。

(追記)入力を受け取るパートを関数にすると見やすくなる。いつもそうだったのはわかってたけど、再帰の中に書くというプレッシャーからそうする余裕がなかった。

G - Banned Substrings

行列累乗。最初は、遷移書くの(複雑すぎて)不可能だろと思っていたけど、最終的にはそこそこの長さで書けた。ただ、めちゃくちゃにバグを入れまくり終了後もやり続けて1時間近くかかった。

(追記)この問題の場合、工夫すると各パートの実装は楽になるがパートが増えたぶんデバッグで死ぬのでやはり地力がないといずれにせよ。方針は、まず長さmin(N, 5)を愚直でやる。残りを行列累乗。ダメ文字列は先頭に全パターン追加することで長さ6だけにする。遷移はシフトとかして2通りだけなんで楽。考察難度の高い実装方針が色々ある。