/ 最近 .rdf 追記 編集 設定 本棚

脳log[20201222] パナソニックプログラミングコンテスト(AtCoder Beginner Contest 186)/E 問題 Throne



2020年12月22日 (火)

最終更新: 2020-12-23T00:48+0900

[AtCoder] パナソニックプログラミングコンテスト(AtCoder Beginner Contest 186)E 問題 Throne

まだ AC をもらっていないし、それどころかひとつの提出もできていないけど、外堀が埋まってきた気がするので経過を書く。

 シミュレーションした。(未提出)

gets
puts$<.map{|ln|
	n,s,k = ln.split.map(&:to_i)
	ss = {0=>m=0}
	until ss[s]
		ss[s] = s
		m -= (s-n)/k
		s += (s-n)/k*-k
		s %= n
	end
	next s == 0 ? m : -1
}

これはサンプルの4つのケースのうち、3番目を除いて正しい答えを出す。3番目の 998244353 897581057 595591169 にもたぶん正しい答えを返すだろうけど、答えがおよそ 250 メガなので数分単位の時間がかかるはず。

N と S と K の3つの数字があるけど、N と K が近接していてしかもべらぼうに値が大きい。ループ1回のイテレーションで全周 N のうち1点だけをテストするのでは最悪 N 回繰り返す。N の上限は1ギガだ。

 たとえば K = N-1 の場合

1回のイテレーションで S-1 の地点に移動する。S 回のイテレーションで玉座に移動することが即座に理解できるが、スクリプトにそれは反映されていない。

 たとえば N と K が偶数で S が奇数の場合

K が2より大きければ(N との関係にもよるが)すべての偶数地点を網羅できるとは限らないが、K が最小の偶数2であっても、スタート地点 S から奇数席離れた玉座に移動できないことはすぐにわかる。これもスクリプトに反映されていない。

 それで?

N と K と S の関係をどういう式で表すのかなあ。LCM だか GCD だかのキーワードは目に入ってるんだけど。


K = N%K という風に再帰的に K を更新していくと最後は 0 に落ち着く。K が 0 になるまでに S をどうにかしたものが K で割り切れれば答えは N/K の倍数±α になりそうなんだけど、S をどうするのか、N-S をどうにかするのか、よくわからない。