ABC179 Eが解けそうで解けなかったからAC回答を書いてみた!

はじめに

aimakerさんのAtCoder Beginner Contest 179での成績:5623位
パフォーマンス:411相当
レーティング:55→81 (+26) :)
Highestを更新しました!

atcoder.jp

コンテスト開始30分後に気づいて参加しました。

ABC179のA, B, C問題を全完できました!

E問題が解けそうでしたが、TLE、WAでした!
 
くやしかったので、次の日にC++の解説放送を見ながらRubyで書いてACを取りました。

問題

atcoder.jp

解法

atcoder.jp

学んだ処理

ja.wikipedia.org

例)(n ,x, m) = (6, 2 ,11)

id = Array.new(m, -1)

まず-1が11項ある配列 id を用意します(鳩が入るための部屋)。

id = [-1, -1, -1, -1, -1, -1, -1, -1, -1 , -1, -1]

 

仮定より数列の初項が 2 なので、id[2] = 0 にします(2番の部屋に0番の鳩が入る)。

id = [-1, -1, 0, -1, -1, -1, -1, -1, -1 , -1, -1]

 

漸化式の処理:前の項を2乗して11で割ったあまりが次の項です。

2*2 = 4

4%11 = 4

 

数列の第2項が 4 なので、id[4] = 1 にします(4番の部屋に1番の鳩が入る)。

id = [-1, -1, 0, -1, 1, -1, -1, -1, -1 , -1, -1]

次の項、次の項と見て行くと、高々m回目で id のすべての項が 0 から 10 の数に置き換えられます(高々すべての部屋に1羽ずつ鳩が入る)。

 id = [-1, -1, 0, 3, 1, 2, -1, -1, -1 , 4, -1]

 

こうして数列の各項の値を配列 id の値に入れていくと、はじめて同じ数(この場合、数列の第5項の4)が2回目に出たときが検出できます(鳩を入れようとした部屋に、既に鳩が入っている)。

id[4] = 5

 

まとめ

これまで「配列といえば左から順に埋めるものだ」とばかり思っていました。

鳩の巣原理でループを見つける解法を理解できたときは膝を打ちました(心のなかで)。