AHC067参加記
はじめに
AtCoder Heuristic Contest 067 に参加し、397位(perf 1304)でした。
考えたことや反省点などを簡単にまとめたいと思います。
結果が結果なのであまり参考にはならないかもしれませんが悪しからずご了承ください。
問題
- 迷路状になっているグリッドマスがある
- 迷路を進む相手を妨害するのが今回のミッション
- スイッチと仕掛け扉(以下扉)を配置して、相手がスタートからゴールまで到達する手数をできるだけ稼ぐ
- スイッチと扉には番号が付いていてスイッチを押すと同じ番号の扉の開閉が切り替わる
- 扉は最初開/閉どちらの状態で置いてもよい
- 相手が理論上ゴール不可能な状態にしてはいけない(ゴールできる範囲で手数を稼がせる必要がある)
解法
ゴールを扉0(閉)で囲んでふさぎ、その扉0(閉)を開けるためのスイッチを扉1(閉)でふさいで・・・を繰り返しました。
公式の解説放送の「線形スイッチ解法」とほぼ同じかと思います。
スイッチを置く位置はBFSで求めて決めました。最初のスイッチ0はスタートからスイッチ0を経由してゴールまでの距離が一番遠くなるようなマスに置き、以下同じ要領でスタートからスイッチ0までの距離が一番遠くなるマスにスイッチ1を置いて・・・を繰り返しました。
この方法だと置くことのできる扉の数が余るので、余りはランダムに扉0(閉)を置いて距離を稼がせる山登りをしました。
スタート時点:ゴール・スイッチの前に扉を配置
ゴール後:状態が有効活用できてない
コンテスト後に試した解法
ゴールの前に追加で扉1(開)~扉9(開)を置くようにしました。コンテスト中に提出した解法ではゴールを守る扉0(閉)を開くためにはスイッチ9~スイッチ1を順番に押していく必要がありますが、扉0を開いたときには今度はゴールの前にある扉1~扉9が閉まっていてもう一回スイッチ1~スイッチ9を順番に押さないといけないという狙いです。
スタート時点:ゴール前に多重に扉を配置
スイッチ0到達時点:新たに扉が閉まっている
ゴールの前の扉は、ゴールからBFSを行い、最短距離の変わり目に距離に応じた番号の扉を配置しました。これだと扉を置く場所とその種類を比較的単純に決めることができます。配置によっては扉が足りなくなる可能性があるため、この手法で使用する扉は最大30枚としました。
また、このBFSで扉を置いたエリア(ゴールからの距離設定が10以下のマス)にはスイッチを置かないように制限しました。スイッチについては、行き止まり(次数が1のマス)に配置しています。
これで本番404位相当。コンテスト中の順位よりまだ低いですが、
- コンテスト中に入れていた余ってる扉をランダムに置いて距離を稼ぐロジックが入ってないので、これを入れる
- ゴールからのBFSで扉を置くときに行き止まりに向かうパスにも扉を配置する無駄遣いをしているのをやめる
扉を多重に配置するこの仕組みを(扉の枚数が足りるかは置いておいて)ゴールだけでなくて、スイッチ0など他のスイッチにも適用できないか・・・となり、上位陣の解法である2のk乗解法への道筋がようやく見えてきそうなところです。
反省点
「コンテスト後に試した解法」は、できればコンテスト中にたどり着きたかったです。
最初は自分で考察しつつ実装もメインで(AIは定型処理の実装補助、提供コードの言語変換、バグ探し)進めていたのですが、後半から自分で粘って考えるのかAIに頼るのか中途半端になって時間を有効に使えなかった気がするので、今回に限れば粘って自力で考えたほうが
良かったかなと思います。
また、「乱択DFSを使ってグリッドから迷路を作る(グラフの辺を削って木を作る)」という手法は、感想戦を眺めるまで思いつきませんでした。こういった手法は汎用性がありそうでAHCの基礎として重要だと思いますが、自身の基礎的な力がまだまだ不足していると感じました。
結果がそれほど良いわけではないのですが敢えてよかった点もあげるなら次の通りです。
- 筋道を立てて考えることはできた
- ビジュアライザの状態遷移を見て状態数のフル活用が必要そうなことには気づけた
感想
レートの向上にはつながりませんでしたが、反省点や「グレイコード」の概念など、勉強になる収穫がいくつかありました。
ここまで読んでくださりありがとうございました。
.png)
.png)
.png)
.png)