%P
の位置だった。3項の掛け算のあとに %P
をくっつけていたのを前にずらして2項の掛け算にするだけで2秒オーバーが1秒未満になった。Ruby にはオーバーフローがないからついテキトーに %P
を付けたり省いたりしてしまうんだけど(%P
が多すぎても少なすぎても TLE の原因になるのだ)、同じ1回の %P
でも位置によって効果がだいぶ違うんだなあ。■F 問題「Easiest Maze」。出力形式難しすぎ。そして問題文が間違っていた。「壁があるときに辺で結ばれていて、長さ K の唯一のパスを構築する(大きさ K の連結成分では十分ではなく、塊やループや3つ以上の端点があってはいけない)」というのでは壁の既成概念が崩壊する。質問と訂正があるのを待つことにして A 問題からの実装を始めることにした。終了の 25 分前に戻ってきたら問題文の修正は終わっていたが、差分を調べるのが面倒で読まなかった。すること自体は難しくなさそうに見えてやりきるのはすごく難しいかも。自分の頭で考えて答えを構築するなら、縦と横の偶奇の扱いがやっかい。だったら機械に長さ K のパスを探索させれば何も考えなくていい。100×100 というのが素朴な DFS にとってどれだけの規模感なのかよくわからない。やばいとは思う。マスの埋まり具合と現在位置でメモ化してもどうか。2、3日前に読んでいた『競技プログラマー ハンドブック』(PDF) で紹介されていた枝刈り手法が使えそう。壁にぶつかって左右に進路が分かれるとき、ゴールがない方の進路に答えはない。なんにせよ時間がなかった。■精進。G 問題「AtCoder Tour」。F より低い青 diff なのを見たので問題を読んだ。現在のマスが終着点だと仮定したときの想定楽しさを元にした BFS でできそう。提出 #54618901 (AC / 413 Byte / 480 ms)。できた。こんな腑抜けた G 問題を置かれると、目の前の問題を解く以外のことを考えさせられてめんどうくさいんだよなあ。■■■精進。F 問題。やっぱりね、「すること自体は難しくなさそうに見えてやりきるのはすごく難しい」。何をするかって、ぐねぐね左右に線を引いて、ラスト2行の帰り道では縦にぐねぐね線を引いて、それをフォーマットして出力する。がんばってやる! 提出 #54644107 (AC / 1676 Byte / 51 ms)。右へ線を引く、下に移動する、左へ線を引く、ぐねぐねしながら左へ線を引く、と関数を分けることで、同時に1つのことだけを考えればいいようにした。文字列化するのも、行を出力する関数と行間を出力する関数に分けて、同時に1つのことだけを考えるようにした。もーたいへん。縦横の偶奇と K の偶奇は調べなかった。予め達成可否を判定することはせずに(できませんから!)、やるべきことをやった結果ゴールにたどり着いているかどうかで判断をした。これは ABC347-D の反省から(「RE/WA を出した方では、不可能なケースを最初に判定するようにしていた。一方の AC 提出の方では、操作をしたあとで、結果が満足しているかどうかで出力を切り替えた。要するに、不可能なケースの判定に漏れがあったのだ」)。■■■F 問題のジャッジがザルだったらしい。まあ、あの大作の出力形式を整えて提出しただけで評価されてもいいよ。■G 問題。「現在のマスが終着点だと仮定したときの想定楽しさを元にした BFS でできそう」について書く。まず、待機するマスは必ずパスの末尾になる。最適を目指すとそうなる。パスがあって長さが決まっていて、残りのターンを費やすのは報酬が最大のマスに決まっている。それがパスの途中にあるとするなら、そのマス以降のパスが蛇足だったということになる。移動を省いてそのターンも待機に費やした方が良い。だから待機マスは必ずパスの末尾になる。▐あるマスに到着したときのことを考える。関心事はそのマスを最終地点とした場合のスコアだから、到着時点での残りターンを報酬に変換してスコアを比較する。スコアがすでに記録されているスコアと同じか下回っている場合は探索を打ち切って良い。なぜか。パスを伸ばす目的というのはより良い待機報酬を求めることにあるのだから、あとから訪れていて残りターン数が少ない探索の枝はそれだけでビハインドを背負っている。それなのにパスに依存したスコアが余分に費やしたターン数に見劣りしているというのだから、これ以上の探索で先達より良いスコアを得る可能性はない。▐もう全部書いた? 提出したあとになって問題があると不安になって、でも実は問題がなかったことがある。BFS で t ターン目の処理をしているときに、隣接マスを t+1 ターン目のキューに入れると同時に t+1 ターン目の状態をその隣接マスに書き込んでいる。このあとさらに t ターン目の処理を進めているときに、さっき t+1 ターン目のキューに追加したマスが出てきてしまったら、t+1 ターン目の状態に基づいて t ターン目の処理をすることになるのではないかと考えた。でもチェス盤を考えるとわかるんだけど、t ターン目のキューと t+1 ターン目のキューに同時に入るマスは存在しないのだった。うまくできてるんだなあ。今までそれを知らずにグリッド BFS を書いてたんだぜ。■■■D 問題。B の降順だと A をスキャンするだけでは済まないみたいなことを書いたけど、具体的には二分探索と中間位置からの効率的な削除が必要だと、平衡二分探索木みたいなものが必要だと思っていたけど、そんなことはなかった。昇順でも降順でも