MC Digital プログラミングコンテスト2023(AtCoder Heuristic Contest 019)参加記

2023/3/18〜2023/4/2に開催されたMC Digital プログラミングコンテスト2023(AtCoder Heuristic Contest 019)に参加しました。

atcoder.jp

今回は2週間の長期コンテスト。いままで、この手のコンテストでは適当にプラスの得点を取れるだけの提出をするだけというのが多かったのですが、今回は期間フルに使って真面目に取り組んでみようという気持ちで臨みました。

今回の結果

確定185位でした。個人的には、なかなか良い結果が出たという印象です。

AHC019結果
AHC019結果

今回のパフォーマンスは、前回につづき青色に到達!レートをさらに伸ばすことに成功しましたとさ。

振り返り

今回、初回提出が大分出遅れた割にはいい結果が出てくれました。

AHC019提出結果
AHC019提出結果

A問題

A - Silhouette Block Puzzle Creation

初日に問題を見てみるも、全然なんにもわからんというのが第一印象でした。とりあえず最初の数日間は考察めいたものをして見たものの、実装の方は全然進まずでした。。

結局、まともらしい提出ができたのが終了1日前の土曜日という有様でしたが、なんとか形は作れたかという結果になりました。

基本方針

シルエット1に対応するブロックの組み方をパズル1、シルエット2に対応するブロックの組み方をパズル2と呼ぶことにします。

評価値の計算方法から見て、良い得点を得るために必要なことは以下の3つになります。(ちなみに、ここの評価値の意味合いも、コンテスト終了数日前にやっと理解できたという状態でした。。)

  • パズル1、2の大きさを、できるだけ小さくすること。

  • パズル1、2で、共通しないブロックをできるだけ作らないこと。

  • パズル1、2で共通するブロックの体積を、できるだけ大きくすること。

とりあえず、大きな塊で共通するブロックを作るのが良いだろうなあ、という発想のもと、以下の要領で実装することにしました。

  • パズル1、2をそれぞれシルエット1、2を達成できる最大のサイズで作成し、全てサイズ1のブロックで初期化する。

  • パズル1とパズル2で共通するブロックの連結方法を探索する。パズル1、パズル2のブロックおよび6つの回転方向をそれぞれランダムで決定し、BFSで探索しながら可能な限り連結する。これを、連結できる候補がみつからなくなる(具体的には、100回程度ランダムで始点を決めた時に候補がみつからないとき)まで続ける。

  • パズル1、2について、サイズ1のブロックがある場合、シルエットに影響ない場合は削除し、残す必要がある場合は可能な限りもう一方のパズルにあるサイズ1のブロックと共通化させる。

  • 上記を1セットとし、時間いっぱいまでこのセットを繰り返して評価の高いものを採用する。

こんな実装で、なんとかコンテスト最終日に、それなりの順位まで到達することができましたとさ。

ちなみに、本当はブロックの回転方向は24通り(6面のうちどれを下にするか×向きの前後左右の4通り)で実装したかったのですが、なぜか動かしてみるとブロックの形が合わなくてエラーになったので、仕方なくエラーが出なかった6通りの実装で妥協することに。。

そのほか、探索の打ち切り方法なんかも色々工夫の余地はあるかなーというところでしたが、最早残り時間もなく。ここで打ち切りという感じです。

最終提出コード

https://atcoder.jp/contests/ahc019/submissions/40300326

振り返り

反省点としては、以下の通り。

  • パズル1、2ぞれぞれで、シルエットが達成できることが確定した時点で共有ブロックの探索を打ち切るべきだったかと。現時点では、余計にパズルのサイズを大きくしてしまっている模様。

  • ブロックの回転方法について、やはり他の解法だと24通り試すことができていた模様。どの辺がバグっていたか見直しが必要だなあ。

  • 今回はコンテストが開始して1週間以上、何もできてない状態でした。実装の開始が遅すぎです。

これまでの実績

前回に続いて、大きくレートを伸ばすことに成功しました。ヒューリスティックは青色目指して頑張ります。

コンテスト実績
コンテスト実績

総括

今回は、実装が大分出遅れたのが一番の反省点。とりあえず時間がありそうだからと後回しにしてたツケが、後々になって時間不足という結果を招いてしまいました。

また、今回のように乱択で適当な解法では、スコアの方も頭打ちになってくるというのがよくわかりました。上位陣の解法等を参考にして、具体的にどのようにすればスコアが伸ばせたかを研究していこうと思います。

ということで、また次回も頑張ります。