以下の内容はhttps://kaede2020.hatenablog.com/entry/2025/06/09/202655より取得しました。


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

0.はじめに

はじめまして、もしくはお久しぶりです。競技プログラミング歴6年目のかえでです。

これは、2025年5月30日金曜日19時から6月9日月曜日19時までの11日間開催された「MC Digital プログラミングコンテスト2025(AtCoder Heuristic Contest 048)」の参加記になります。

今回は長期コンテストでは初の黄パフォになるかもしれません(暫定111位)。システムテスト前なので、ぜひ耐えてほしいと思います。

コンテスト中に書いた記録なので、ところどころ読みづらい箇所があるかと思います。夢中になると、記録もせずにひたすら試したり、デバッグしたりしていました。

提出をすると一息つけるのですが、なかなかローカルで100テストケースを試したときにスコアを更新するのが難しく、提出する機会が少なかったかもしれません。

それでも、この参加記がAHCに参加している方、AHCに参加してみたい方の少しでも参考になればと思い、公開します。読んでくださった方の参考になる箇所が少しでもあればうれしく思います。

1.問題の概要

atcoder.jp

  • 与えられた K 本のチューブ絵の具(色は (C,M,Y) で表現)だけを使い、パレットで色を混ぜ、H 個の目標色を順番どおりに 1 g ずつ高橋画伯に渡す。
  • パレットは20 × 20 のマスでできている。上下左右の仕切りを上下させてマスを結合/分割でき、結合した連結成分を ウェル と呼ぶ。
    1 マスにつき最大 1 g 入る。ウェル内では色は常に完全に混ざる。
  • 許可される操作(最大 T ターン)
    • 操作1    1 i j k    マス (i,j) が属するウェルにチューブ k から 1 g 入れる(入りきらなければ余りは即廃棄)
    • 操作2    2 i j    ウェルから 1 g 取り出して高橋画伯へ渡す(残量 1 g 未満は取り出せない)
    • 操作3    3 i j    ウェルから 1 g 廃棄(残量不足なら残量全て廃棄)
    • 操作4    4 i1 j1 i2 j2    隣接 2 マス間の仕切りを出し入れする
  • 操作 2 は ちょうど H 回 行わなければならない。
  • スコア:取り出した色と目標色のユークリッド距離和 をE、操作 1 の回数 をVとすると、絶対スコア = 1 + D·(V−H) + round(1e4·E)

  • スコアを最小化する
2.「例を見る」からビジュアライザを見る

問題文の「例を見る」リンクからビジュアライザを見ます。

絵の具を足して、絵の具の色が混ざっている様子がわかります。こんな複雑な区切りを作るのは難しそうだと思いました。もっと単純なものから始めることを考えます。

例を見る
3.最初の提出

一番近い1色を貪欲に選びます。

提出すると同じスコアが並んでいました。

絶対スコア:109690905

11位/98人中

つぎに、最初に2色を混ぜて1g提出し、2回目以降は、絵の具を1色単独で出すか、今パレットにある色と混ぜて1g提出するかを、目標色に近い方を選ぶ貪欲をします。

提出します。

絶対スコア:54187867

相対スコア:10位/131人中

ここで、入力生成方法を確認します。

入力生成方法からみたDの値とその出現確率

Dの値と出現頻度グラフ

Dの大きさによってスコアへの影響が異なるので、Dの値によって戦略を変えることにします。

Dが小さいときは、精度を上げるために、ビームサーチを行うことにします。

絶対スコア:52092102

相対スコア:16位/182人中

ここまで順調だなと思います。

順位表のトップを見ます。コンテスト時間は2時間半が経過していました。

順位表のトップ 2025年5月30日午後9時半現在

自分の相対スコアとは倍以上の差がありました。考察を始めないといけないと思いました。

全部ビームサーチにしてみます。(詳細は忘れました)

絶対スコア:50494812

相対スコア:33位/263人中
4.最初の考察

コンテスト2日目、2025年5月31日土曜日の朝です。

順位表のトップ:2025年5月31日AM9:35現在

解法が割れていそうです。私はというと、現在103位です。

トップとのスコア差は約6倍。私の今の絶対スコアは5050万くらいなので、840万くらいまで減らせるということでしょうか?(適当)

103位/391人中

さて、考察です。

スコアの計算方法をよく見ます。

操作1とは「あるマスに1グラム絵の具を出すこと」です。

得点計算方法(AtCoderの問題文より引用)

パレットには1000グラムまでならペナルティなしで絵の具を出せることを意味しています。最終的に操作2で全て提出すれば、D(V-H)が0になります。

ただ、色の誤差のペナルティが大きいので、Dが小さいときは絵の具をたくさん使ったり、捨てたりしても、まだその方がスコアが減るのかもしれません。

したがって「誤差を減らすこと」を考えます。

その場合、できるだけパレットに色を広げることが良さそうで、近くなったら提出していくのが良さそうです。またパレットの連結はコストなしに自由に操作できることがわかっています。

まず、パレットを20区画に分けます。1つの区画には20グラムまで追加できる感じ。

  • 1行ずつ(20マス)を1ウェルにした20区画を作成する

何を選ぶかはよくわからないので、20個ランダムに選びます。

その後は最初の色に近づけるように今あるパレットの一番良い場所に1グラム追加します。その次は2番目に近い方、3番目に近い方、…と色を足していきます。

これ、多分一番近くなるのが足したときとは限らない気がしてきました。

全部作った後に1~1000番目の色をどのタイミングで取るかを考える必要がありそうです。

時間いっぱい、ある箇所の色を変えたり、取るタイミングを変えたりする焼きなましをやってみると良さそうです。

実装して提出をします。

絶対スコア:35519174

相対スコア 61位/396人中

1色追加し、1色削除を続けるが、残りの提出数が今あるパレットの絵の具の量になったら、色を足して絵の具を提出するか、そのまま絵の具を提出するかをスコアの良い方を選択するように改善します。

提出をします。

絶対スコア:16707154

相対スコア:23位/404人中

さらに改善して、そのウェルの最後の提出のときに絵の具を足さずに提出した方がスコアが下がるなら採用する(D絵の具を足す+誤差×10000>絵の具を足さない誤差×10000)ことにします。

実装をして提出をします。

絶対スコア:15940598

相対スコア 33位/560人中

次の改善として、パレットの区切り方を変えてみます。

結果は微妙でした。

seed0のビジュアライザ

2色を一度に変える近傍を追加します。

改善したので提出をします。

絶対スコア:14850683

相対スコア 36位/613人中
5.さらに考察

コンテスト3日目の朝です。

昨晩は2色を一度に変える近傍を追加した後は、壁の作り方を自由に変えることを試していましたが、まだうまくいきません。seed11のビジュアライザでは色が全然合っていないし、拡張のされ方も窮屈です。

seed11のビジュアライザ

最初は一番左の2列に絵の具を入れて拡張していこうと思ったのですが、これもまた難しい…。バグらせ続けて疲れてきます。

seed11のビジュアライザ 開始時

今考えているのは、他のウェルと接する数が多いといいなあということです。

1行ずつ色を変えていたので、区切りを外した時に上下の色としか混ぜることができません。焼きなましをしても、隣接ウェルと混ぜることが採用されていませんでした。

そうか、最初に色順にソートするといいのかな。

終わりの調整をHの981個目の提出時から920個目の提出時に修正しました。

提出をします。

絶対スコア:14379135

相対スコア:40位/657人中
6.まだまだ考察

問題文を最初に読んだときから考えていたことがありました。

それは、色ではないものに置き換えられないかということです。パラメータが3つなのだから、3次元空間と考えれば、近い色を作ることがもう少し簡単になるのではないかと思いました。

今、ウェルを拡張するとか、隣の色と混ぜるということを考えたとき、2次元グリッドで考えなくても良いのではないかと思っています。各ウェルのMAXサイズの総和がN×Nを超えない範囲で各ウェルを拡張していき、最後にそのMAXサイズと、色を混ぜたウェルが隣接するように配置すればよいのではないかと思っています。

7.横道

うまく考えがまとまらないので、ちょっと中断します。

パレットの区切る方を変えてみます。

2×5を左寄せで10個、右寄せで10個作り、真ん中の6列目から15列目は1マス区切りの空きスペースとすることにします。

このプログラムを改善します。

隣接ウェルとのマージ方法が簡単な実装に落とし込めずにいます。

  • 各ウェルの代表マス(絵の具の追加はこのセルに行う)
  • 壁区切りの読み込み(最初に出力する壁区切りは入力通りに出力するだけ)
  • 壁区切り通りに各ウェルに連結されたマスをUnionFindで管理

この形で拡張しようと思いますが、またもバグらせます。

seed0のビジュアライザ

元の形に戻して、近傍を追加することにしました。

提出をします。

絶対スコア:14184662

相対スコア 44位/685人中
8.ウェルのサイズを可変にする

今は2つのウェルを混ぜて均一にする(その後また元のサイズに戻す)近傍しかありません。1マス切り出して隣接するウェルに混ぜる近傍を追加したいと思っています。

その実装をひたすらバグらせています。(とにかくずっとバグらせています)

シミュレーションするときと、実際に採用するときの仕切りの管理がうまくいっていないようです。

自分で実装するかと思いつつも、手が進まず、生成AIに書かせようとしてバグらせて時間を費やしてしまいました。

やっぱり無理かも。

一旦やめて、パレットの区切り方を5×5に変えました。

seed0のビジュアライザ

改善したので提出をします。

絶対スコア:13978295

相対スコア 48位/719人中

こんな形にパレットを区切ってみたら、マージが楽になるかな。

仕切りの変更を考える
9.バグに気がついた

今更なのかもしれませんが、プログラムには「隣のウェルとの仕切りを取って、混ぜた後、もう一度仕切りを入れる」という近傍を選択したとデバッグ出力がされているのに、実際の出力では、一度も操作4がないことに気がつきました。

え、そんな。

10.自分でコードを書く

コンテスト4日目の朝です。今日は仕事なので、早朝に起きて出勤前にAHCに取り組みます。昨夜は4の操作を出力するようにChatGPTに指示していましたがうまく修正できませんでした。今までウェルのマージを行っていなかったことに気がついていなかったのも、ChatGPTまかせにして自分でコードを書いていなかったからです。デバッグをしているうちに、自分で書いてあるプログラムの内容も覚えてきたので、自分でコードを書こうという気持ちになりました。

これを機に、毎回最初から最後までシミュレートしてスコアを計算していたものを、変更後からの計算に変えるように改善したいと思います。

バグらせたままですが、出勤します。

帰宅しました!

続きをやります。

初めて操作4を見ました。

あ、でも何もないところで仕切りを取ってる…(意味なし)

seed0のビジュアライザ

うーん、スコアは合うようになったものの、最初のころより、スコアが悪化してしまいました。

色の計算がうまくいってないのかもしれません。

長いバグ取りの時間が始まりました。

11.長いデバッグの時間

コンテスト5日目です。昨日はデバッグをしているだけで終了しました。操作4が動くようになったので、また指示をしてChatGPTに実装させる方法に戻しました。

今日もまたデバッグからのスタートです。

デバッグ出力を入れて、地味に間違っている箇所の特定をがんばります。

あ、エラーがなくなったかも。

そう思ったのは3時間くらい経過した後でしょうか。

マージして1gより少ない提出をしてWAになっていたのですが、2gのウェルと1gのウェルを混ぜて分割すると1.5gになります。そこで1g提出すると残りは0.5gなのですが、1gあるようになっていました。そのような場合は最初から2g足して分割後に2gあるようにしました。各ウェルに1gある状態をキープするように修正します。

100テストケースを試して全てACすることを確認します。

全体的に誤差をこれまでの6割程度に削減できているようです。highestを更新したテストケースがありました。seed13では、180331から133909になっているのが確認できました。

Dが167と小さいので、誤差が小さくなった分、スコアが改善されているのがよくわかります。

まだ最後の回収(Dが大きいときは誤差によるペナルティとDのペナルティを比べると提出した方が良い場合がある)のロジックを入れていないので、Dが大きいときはスコアがまだ大きいです。

seed13 Score=133909

最終の回収部分のプログラムを追加します。

12.ついに操作4が実装できた

WAが続いて悪戦苦闘しつつも何とか最終回収部分も追加します。そして、近傍も追加して、操作4を加えたコードができあがりました。

100テストケースの結果は平均89%になり、前回の提出より1割ほど改善しました。

提出をします。

気がつく人がいるかもしれないので注記です。今日は水曜日ですが、仕事はお休みをいただいているので、昼間からAHCに取り組めています。

絶対スコア(注:今日は平日ですが、仕事は休みです)

64位/890人中

順位表のトップです。

トップの順位表:2025年6月3日午後2時35分現在

え、いつのまにか上位の顔ぶれが変わっています。

そして、この相対スコア。

何が起こっているのでしょう。まだコンテスト中盤なので、差は詰まっていくと思うのですが、逆転するのは難しく見えました。

私はといえば、絵の具を追加して誤差をまだ少なくできる見込みがあるのと、絵の具を最後に残さないようにうまく提出することができていないので、伸びしろはまだまだあります。

さらに順位を上げていきたいと思います。

食事もせずに取り組んでいて、先ほど小さな羊羹を食べました。

おいしかった。

AHCをやる前に食べたときは、羊羹をおいしく感じるのはまだ先だなあと思っていたのですが。

というわけで、お昼ご飯を食べたいと思います。

今のseed0のスコアは279291です。

序盤は誤差が少なく提出できていて良いのですが、最後のつじつま合わせがイマイチなのがよくわかります。

誤差の和は21.8138です。Dのペナルティが大きいので、もったいないです。

seed0のビジュアライザ Score=279291

終盤のDペナルティの影響負荷を非対称S字関数で行います。

改善したので提出をします。

絶対スコア:12396914

相対スコア 64位/893人中

さて、ブログを書かないまま時間が経ってしまいました。

スコアが良くなって気を良くしていましたが、その後改善できずにいました。プログラムを良く見ると、隣接ウェルの仕切りの出し入れに関して、全探索していないことに気がつきました。生成AIに書かせると、実装したつもりになっていて、やっぱりダメですね。

実装し直します。

うーん、うまくいかなかった。

一旦、別の方向にします。

100テストケースの結果をもう少し詳しく見ることにします。

KとDの値でテストケースの平均を取ってみることにしました。

現在、トップとのスコア差が7倍くらいあるので、どのケースで相対スコアの点数を稼いでいるのかを調べないといけなそうです。

100テストケースの結果

Kが少ないときはウェルの数は少なくても良い?

あ、違う。

  • K(絵の具の種類数)が多いときはウェルの数は少なくても良く、逆にKが少ないときはウェルが多い方が良いのかも。

コンテスト5日目にしてやっと問題の性質に気がついたように感じました。当たり前なのかもしれませんが、元の絵の具が少ないほど、ウェルでいろいろな色を作らないといけません。それに気がついていませんでした。

ウェルの数を最大50個にしました。

ウェルの容量をこれまでの16から8にしたので、スコアが悪化したものができました。

100テストケースの結果

Kが10以下、かつDが1000以下のときは50個のウェル、それ以外は25個のウェルを使用することにします。

100テストケースの結果

今一番良いスコアはseed68のScore=107046です。

seed68のビジュアライザ

改善したので提出をします。

絶対スコア:11826793

69位/909人中

夕食を食べるのを忘れていたので食べます。(何時かは書きませんが、普段夕食を食べる時間はとうに過ぎていました。)

実行時間を伸ばしてみます。すると4%ほど改善したので、高速化をします。平均で2%ほど改善しました。

絶対スコア:11749562

相対スコア 70位/910人中

この後の改善方法を考えます。

  • ウェルの数を入力によって変える
  • ウェルを使った色パレットを適切な色に調整する
  • 近傍でランダムで選んでいる色を貪欲である程度良い方向の中から選ぶ
  • 評価関数の調整

思い出したので、順位表のトップを見ます。順位表は情報がいろいろと含まれているので、定期的に見なければいけません。と思いつつ、すぐに忘れてしまうのですが。

え、不思議な順位表。

トップの順位表:2025年6月3日21:56分現在

でも私の相対スコアは変わっていない。

どういうこと?

私の順位は71位

貪欲でもう少し良い解にできそうだと思いつつも、またもバグらせ中。

1gより少ないウェルから絵の具の提出を行っています。

2個WAが出ています

相対スコア 65位/921人中

西村さんを抜き返したいと思いつつも、近づけはするものの、追い越すことができずに悔しい時間が続いていました。

西村さんを追い越せない!

就寝します。

13.ウェルと提出する絵の具の誤差を減らす

最後に残る色と提出したい色の誤差が大きくて、悩んでいました。ずっと。

一つ思いついたので、やってみたいと思います。

  • トランプを配るように、ウェルに作る絵の具を分配します。
  • 各ウェルごとに、提出順にその差(距離)を足します。
  • ウェルごとの和の合計が小さくなるように提出する絵の具を焼きなまし(もしくは山登り)で入れ替えます。
  • 各ウェルは事前に決められた絵の具を順に作ります。

頭の中にはTSPがあります。近い順に作っているので、最後に誤差が大きいものが残るというのは、まさに貪欲にルートをまわるときと似ていると思いました。CMYを3次元空間だと考えれば、その距離を縮めることに意味はありそうです。

実装してみると、スコアが悪化しました。

初期スコア941243→SA後726351(seed0)今のseed0のベストスコアは245056なので、3倍以上の悪化です。

うーん、イマイチ。

いろいろ試しているうちに、昨日のバグの原因に思い当たりました。

ウェルの数を50にしたときにバグっているとわかったので、ウェルの上限チェックを行っていないように感じました。プログラムを見直すと、25個のときの上限、16で固定になっていました。50個のときは8にします。

消えた!

バグが消えました!

100テストケースの平均は228085まで下がりました。

100テストケースの結果

提出をします。

絶対スコア:10912206

相対スコア 62位/935人中

やった!

絶対スコアがかなり下がりました。

そして、順位表のトップも混戦(見るたびに人が違う)。

順位表のトップ:2025年6月4日午前7時42分現在

ウェル50個とウェル25個の切り替え条件を調整したら、さらにスコアがよくなりました。

Dが3000より小さければウェル50個に、それ以上ならウェルを25個にしました。

100テストケースの結果

提出しようと思いますが30分の提出制限にひっかかります。こういうときはとても待ち遠しいものです。

長期AHCは30分に一回の提出制限がある

提出します。

あれ?

WA

1ケースでWAが出ていました。

しかし、相対スコアは上がっています。

相対スコア 56位/936人中
14.バグの修正

コンテスト6日目、6月4日水曜日の夜です。順位表は見るたびにトップが違います。スコアを確かめた後、低いスコアに戻しているのかもしれません。

順位表のトップ:2025年6月4日午後8時30分現在

さて、自分はというと、1000テストケースで6ケースほどWAが出る状態でした。1gに満たないものを提出しています。

どれも0.97とか1より少し足りないくらいです。

プログラムを見直しているうちに、容量のチェックをきちんとしていないことに気がつきました。容量を超えた絵の具が実際は捨てられているのに気がつかず、実際と異なる量が記録されている箇所があるのかもしれません。

見直してみますが、まだWAが出ます。

…うーん、違いそう。

あまりにもわからないので、もう一度提出することにします。
やっぱりWAが出た。

done[w]=1;

これ何?

あれ?

いや、これが原因ではなさそう。(修正したけど)

2つのウェルをマージする際、2つのウェルを足した容量が1g以上であること、マージしている状態のウェルではないこと、同じウェルではないことを条件に足します。

やっと、やっと、1000テストケースでACしました。

絶対スコア:10643129

相対スコア 62位/967人中

ところが、提出前の7,439,315,909より、相対スコアが下がってしまいました。

あれ?

マージ部分を改善します。

提出をします。

絶対スコア:10519895

相対スコア 60位/973人中

疲れたので寝ます。

15.近傍に操作4(ウェルの仕切りを外す)を入れる

コンテスト7日目の朝です。見るたびにトップの順位表が違うのが本当に面白い。

順位表のトップ:2025年6月5日午前9時17分現在

トップの方たちは解法が異なるので、提出によって順位表の変動から推測されるのを嫌っているようです。それでもこの順位表は今のトップで合っていそう。

私の順位61位

私はといえば、相対スコアは変動しているものの、順位にはさほど影響がないようです。

ところで、焼きなましの近傍からは「隣接ウェルの仕切りの取り外し」が消えているのでまた追加したいと思います。(バグったときになくなっていた)

うまくいかない(採用されない)

試行回数の平均は794回。誤差の和の平均は20。

うーん、もっと誤差を下げたい。

16.Dを条件にした場合の相対スコアの割合

金曜日です。残り時間も少なくなってきました。現在の順位は1014人中84位。推定パフォーマンスは2118です。

トップとの相対スコアが3倍あるので、どこが自分のスコアを獲得しているところなのかを調べることにします。まず、Dで場合分けをします。

提出をする際に、調べたい値の範囲外のDだったときにWAが出るようにすると、ACした数からテストケースの数とその相対スコアがわかります。

1回調べた後に次の提出まで少なくとも30分はかかるので、その間に他の人の提出があると状況が変わり、正確な値は測れませんが、何となくは傾向がつかめると思います。

50テストケースの相対スコア:6,640,288,364(100%)

  • 条件1:Dが100以下(20ケース)の相対スコア:2,692,753,895(40.5%)
  • 条件2:Dが100-1000の相対スコア(12ケース):(引き算で概算)2,152,688,950(32.4%)
  • 条件3:Dが1000-10000(18ケース)の相対スコア:1,794,845,519(27.0%)

なるほど、Dが大きいのがダメで、Dが中程度が得点源のようです。

それに1,2,3の出現率は同じはずなので、16か17テストケースくらいになるはずなので、偏りがありそうです。

システムテストの2000テストケースにおいては等確率で1,2,3のケースが出現すると考えて計算し直すと、今よりも相対スコアは良くなりそうです。

引き算で全体から引いたけど、相対スコアが変動していたら、全然違う可能性があるかも?

次に絵の具の種類Kの数で場合分けをします。

50テストケースの相対スコア:7,429,893,204(100%)

  • 条件1:Kが4-12(24ケース)の相対スコア:2,105,145,166(28.3%)
  • 条件2:Kが13-20の相対スコア(26ケース):(引き算による概算)5,324,748,038(71.7%)

んー!やっぱり色が少ないときがダメなんだ。

貪欲な初期パレット作りが必要そう。

  • Tmax(調べていない。後から調べる?)

サイズの大きいパレットで色を作って、できた色を1g確保する。このアイデアはどうかな。

さて、誤差の総和が20を10にするには、1色0.02の平均誤差を0.01にする必要がある。そうか、1000個の色の誤差をそれぞれ見なくてはいけなそう。最後の25個の提出ですごく平均を悪化させていそう。というか、追加する絵の具が多い(無駄になっている)のかもしれないし。計算して絵の具を足したい。

絵の具を足して混ぜていくと最終的に1色になる。現色(K)を足して色が変わることが大事。パレット上の絵の具は少ない方が良い。

ビジュアライザを見ると上下のマージがされていません。修正します。また、50個固定のウェルの方が良さそうなので、ウェルの数の場合分けをやめました。

100テストケースをまわすと、6.6%改善していました。

100テストケースの結果

提出をします。

ついに1000万をきり、9787234になりました。

おっしゃ!と思わず声が出ます。

昨日ライバルの皆様に相次いで抜かされて悔しく思っていたので、うれしくなります。

絶対スコア:9787234

相対スコア 61位/1014人中

順位表のトップはまた変わっています。トップが潜伏してしまったようです。

順位表のトップ:2025年6月6日午前11時現在

Kが少ないときは、貪欲で初期パレットを作ると良いかも。

あとDの出現率をもう一度きちんと調べておこう。

初期パレットをランダムから変更。

100テストケースの結果

提出します。

絶対スコア:9699901

相対スコア 59位/1018人中
17.ついに最後の週末が来た

コンテスト9日目、2025年6月7日土曜日の朝です。昨夜はあまりにも疲れていて考察が進まなかったので、早めに就寝しました。今朝はだいぶ元気になりました。

順位表で自分の順位とトップの順位表を確認します。改善していかないと、ここから一気に下がっていくはずなので、がんばりたいです。

現在の順位:70位/1060人中

順位表のトップ:2025年6月7日午前8時現在
18.今の課題

土日で改善したい点です。

  • 絵の具を追加すると色の多様性が確保されるが、その分余分な絵の具の追加に対するDのペナルティが解消できず、スコアが悪くなる
  • 絵の具の追加量を減らすことと、色の多様性を確保することのバランスを上手に確保する

今のベストはseed68のScore=91700です。10万をきれるんだ~という感じ。

seed68のビジュアライザ Score=91700

1000提出までの経過

Dが167なので、最終的に55グラム残っているので、9185が絵の具追加分ペナルティ、84666が誤差ペナルティで93851が最終スコアになるます。(ビジュアライザと違うもので計算してしまった…。わかりづらくてごめんなさい。)

色の多様性にプラス評価、絵の具の残量に応じてペナルティを配分するものの、うまくいきません。結局、最終的に50個のウェルを持っているのがダメそう。

100テストケースの結果

今のseed0はScore=213755です

seed0のビジュアライザ Score=213755

うまくいかないので、最後の提出(絶対スコア:9699901)のプログラムに戻します。最初からプログラムを見直します。

  • Dを考慮する重みづけのタイミングを変更しました
  • 貪欲に操作4(マージのみ)で提出が抜けていたので入れました

100テストケースを試すとはっきりと良くなっているのがわかりました。

100テストケースの結果

提出をします。土曜日の最初の提出ができたのは午後7時を過ぎていました。

絶対スコア:9233706

相対スコア 70位/1087人中

mooakiさんは抜かせたけど、yoichiroさんはさらに先を行っています。追い越したいなぁ。

ライバルの皆様
19.最後の日曜日

コンテスト10日目、2025年6月8日(日)の朝です。コンテストは明日の午後7時までですが、明日は仕事なので、実質今日が最終日です。

現在の順位は、1117人中74位。まだ2桁順位を保っています。

相対スコア 74位/1117人中

順位表のトップは、また上位が潜伏してしまっている様子。

MathGorillaさん、Kiri8128さん、yosupoさん、saharanさん、yunixさん、montplusaさん辺りは1桁順位の人だと思いますが、下の方にいます。全員がベストを提出したときにどうなるのかな。興味津々です。

順位表のトップ:2025年6月8日午前9時現在
20.今自分が書いている解法の説明

私の解法を詳しく書いていませんでした。シミュレーション結果を評価関数に使った焼きなましで解を改良しています。

  • ウェルは50個固定。2×4の8マスを1ウェルとし、縦に10個、横に5個並べて50個を作っています。
  • 最初に全てのウェルにK種類の絵の具を1gずつ入れます。余りは「2 色ブレンド(1 g+1 g)」を 色空間で最も離れるように選択します。まだ余った時は適当にKの中から1gを入れます。
  • H提出のシミュレーションをしたスコアで評価します。下記5種の手で最良を選びます。
    • 提出のみ
    • 1色加える
    • 隣のウェルと混ぜて1色加える
    • 2色加える
    • 隣のウェルと混ぜる
  • 評価は色の誤差のみ、末尾 100 提出で徐々に D×余分な絵の具量のペナルティを乗せていきます。
  • 焼きなましは下記を入れた後、再シミュレーションします。
    • 1色追加
    • 1色削除
    • 先頭の色を変える
    • ウェルの位置を変える
    • 同色の2g以上まとめ投入
    • ウェルをマージする
  • その後、各ウェルで最後に提出する絵の具の前の追加する絵の具を取り消した方がスコアがよくなれば、絵の具の追加を取り消します。
  • シミュレーションが時間がかかるので800回くらいしか試行できません。誤差の和の平均は17くらい(スコアにすると17万)。余分な絵の具は46gくらい(ペナルティは平均1万4千万くらい)です。
21.最終目標
  • SA で初期解 → ビームで後半 200 手だけ改善

を目指すことにします。ChatGPTに戦略を立ててもらったところ、1週間かかるって言われたのですが…。

マージがバグって全部一つになってしまった…。

マージがバグって全部1つになった

うーん

seed0のビジュアライザ

1日かけてうまくいきませんでした。

こんな感じに連結しているウェルがきちんと自分の思ったように管理されているかとデバッグしたり、色や量が合っているかを見ました。しかし、どうしても合わないところが出てきます。
[DBG] idx=-1 groups: {L0:0,} {L1:1,2,} {L3:3,4,} {L5:5,6,} {L7:7,8,} {L9:9,14,} {L10:10,11,} {L12:12,13,} {L15:15,16,} {L17:17,18,} {L19:19,} {L20:20,21,} {L22:22,23,} {L24:24,29,} {L25:25,26,} {L27:27,28,} {L30:30,35,} {L31:31,32,} {L33:33,34,} {L36:36,37,} {L38:38,39,} {L40:40,45,} {L41:41,46,} {L42:42,43,} {L44:44,} {L47:47,} {L48:48,49,}
err= 115.484 V= 1052 opsz= 2075

元のコードに戻ろうかなと思ったのは午後11時を過ぎていました。

ずっとデバッグをしていたから、プログラムをすっと読めるようになっていました。

2800msから2900msに試行時間を変更し、コードをリファクタリングします。少し良くなったので提出しましたが、絶対スコアは少し悪くなりました。

相対スコアはほとんど変わっておらず、順位も同じままでした。

朝に比べるとだいぶ順位が下がって、今は88位です。

絶対スコア:9431853

相対スコア 88位/1159人中

もう寝ないとなあ。

目も疲れたし、タイピングをし過ぎて、右腕が痛いです。左手は大丈夫なので、タイピングの癖なのだと思います。右腕に力が入ってしまうみたい。

1000テストケースを試したら3WAでした。1g未満の提出を行っていました。全てに確認用の条件文を入れます。

結局、見つけることはできませんでした…。

月曜日も仕事の合間にがんばったものの、ダメでした。

睡眠不足です。眠い…。

22.終わりに

コンテストが終了しました。暫定111位でした。週末はたくさん時間をかけたけど、順位を上げれずに、悲しい気持ちで終わりました。

暫定111位/1217人中

午後9時からは感想会スペースも開く予定です。

コンテストが終わって、他の人の解法を見ているうちに、だんだん元気になってきました。みんなすごい!そして、みんな苦労している。

うれしかった気持ち、苦労した気持ちにとても共感しました。

システムテストが不安でしかないけど、また次のコンテストに向かって立ち向かっていければと思っています。

おもしろい問題でした。writerのwataさん、ありがとうございます。そして、コンテストに取り組んだ時間は、自分にとって、やっぱり大切な時間だと思いました。

23.最終結果(2025年6月15日)

システムテストの結果が出ました。暫定111位より少し上がって106位になりました。

結果106位/1205人中

全てACすることはできず、2000テストケース中WAが13個出ていました。AHC Ratingは65上がって1953になりました。

黄色になりたいなぁ。

AHC Rating

きりさんのAtCoder Graphs でAHC Ratingの各コンテストの寄与を可視化します。まだ伸びしろがありそうです。

AtCoder Graphs

AtCoder Graphs より(AHC Rating の寄与を可視化したグラフ)

さて、コンテスト中に調べなかったTmax別の獲得スコアです。

なぜ調べなかったのかといえば、それは

  1. Tmaxが大きいときの自分の相対スコアは小さいのだろうなあと思ったから
  2. そして、Tを大きくするには「厳密に混ぜる」ことをしなければならないので、その実装ができない自分がやってもしかたないと思ったから

です。しかし、コンテスト後に想像以上にスコアに寄与していなかったことがわかりました。コンテスト終了後に概算を出してみました。

全体の相対スコアを4,967,305,207とします。

Tmaxが10105以下のとき(12ケース24%)・・・3,801,996,348(76.5%)

Tmaxが10106以上の25512以下のとき(19ケース38%)・・・1,154,679,831(23.25%)

Tmax>=25513のとき(19ケース38%)・・・10,629,028(0.25%)

やはりTを最短で終了させる方向でがんばってよかったことがわかりました。

Tmaxでみたときの獲得スコア 公式解説タブの詳細順位表より

1位のmontplusaさんとの比較 公式解説タブの詳細順位表より

この後は復習をがんばりたいと思います。

AHCラジオや参加者の方が書いてくださった解法記事を見ながら、Tmaxが大きいときの誤差を減らすプログラムを書いてみたいと思っています。

www.youtube.com




以上の内容はhttps://kaede2020.hatenablog.com/entry/2025/06/09/202655より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14