URL
https://community.topcoder.com/stat?c=problem_statement&pm=11434
概略
1∼N のスロットが1列に並んでいる.プレイヤーは常にスロット 1 の中身しか取得することができない.ゲームの目的は,開始時にスロット M にあった中身を取得することである.
スロットには2通りの操作を行うことが出来る.
Divide
- N を割り切れる素数 p を選びスロットを [1,Np],[Np+1,2Np],… に分割する.この内,目的のスロットを含む部分列のみを保持する.その後,N←Npとし,スロットの番号を 1∼Np に振り直す.
Shift
- スロットを左/右にシフトする.シフトするとスロット番号が −1/+1 だけ変化する.スロット 0 は N に,N+1 は 1 に別途移動する.
最低で何回操作をすれば目的を達成できるか.
方針
全然できなかった.調べたら「Divide
とShift
の操作は可換」ということがわかって(証明は知らない)そこからはノーヒントで行けた.これで250ptなんだ…
Shift
は数えるだけなので先にDivide
を行う.Divide
のやり方は高々、2^(素因数の数)
だから全列挙してやればいい.あとは各々についてShift
の回数を求める.
のんきに数えてたらTLEしたので,剰余で考える必要があるのだが,これが難しかった.右にShift
する場合の式がよくわからなくて,手元のサンプルと帳尻を合わせるように書いたら通った(最悪)
[展開する]