問題. Golf Gophers
18ホールあるゴルフ場の各ホールにちょうど1つの風車がある.毎晩, 番ホール(
)にある風車のブレード数を任意に
に決めて, 0 番目のブレードが真下にあるように設定する.ただし,ブレードは時計回りに
と番号付けされている.
各風車のブレード数を設定した後に, 人のゴルファーがそれぞれ1つの風車を独立かつ一様ランダムに選択して,半時計回りに1ブレード分だけ回転する(真下にあるブレード番号が
のとき,回転後に真下にあるブレード番号は
).翌日の朝に各風車の真下にあるブレード番号が確認できる.
整数 が与えられる.上で説明した18ホールの各風車のブレード数を決めるクエリを高々
回行い,レスポンスの翌日の各風車の真下にあるブレード番号をもとにゴルファーの人数
を求めよ.ただし,
は1以上
以下の整数である.
制約1:
制約2:
解法.中国剰余定理
中国剰余定理(中国剰余定理と法が互いに素でない場合への拡張 | 高校数学の美しい物語)をもとにクエリを構成する.中国剰余定理(Chinese remainder theorem)とは,互いに素な整数 に対して,
本の連立合同式
(
) を満たす整数
が 0 以上
未満の範囲に唯一に存在することを述べた定理である.
番目のクエリで行う各風車のブレード数をすべて同じ整数
とする.このクエリに対して,翌日の各風車の真下にあるブレード番号の総和を
とすると,
が成り立つ.したがって上手く を設定すれば中国剰余定理から 0 以上
未満の整数を一意に求めることができる.ここで,
とする.各異なる
は互いに素で,
なので,入力の制約を満たすどんな
に対しても高々 7 回のクエリで答えを求めることができる.
計算時間:
インタラクティブ問題のローカルでのテスト方法は次を参考.
Google Code Jam 2019 Qualification Round : Dat Bae - 忘れても大丈夫
ブレード数を一定にすればどうにかできるのではと考えたけど上手く構成できなかったのでkmjpさんのブログを参考にした.
Google Code Jam 2019 Round 1A: B. Golf Gophers - kmjp's blog
中国剰余定理を知った時は目から鱗だったけど,これ知らなかったとき思いつく自信がまったくない.