Official

C - Repsept Editorial by kyopro_friends


与えられた数列を \(\{a_i\}\) とします。

問題は「\(a_i \equiv 0 \bmod K \) となる最小の \(i\) を求めよ」と読み替えられます。したがって、\(a_i\)\(\bmod K\) で考えればよいことがわかります。

数列は次のような漸化式で計算できます。

\(a_i= \begin{cases} 7 & \bmod K & (i=1) \\ 10 a_{i-1}+7 &\bmod K & (i \geq 2) \end{cases}\)

この漸化式に従って計算することで、数列の \(N\) 項目までの\(\mod K\) での値を \(O(N)\) で求めることができます。

また、この漸化式より、\(a_i\) に同じ値が出てくるとその先は繰り返しになることがわかります。

よって、鳩ノ巣原理より、高々 \(K\) 項目までを計算すれば十分であることがわかります。

以上よりこの問題を \(O(K)\) で解くことができました。

C言語での実装例は以下の通りです。

#include <stdio.h>
int a[1000001];
int main(){
  int K;
  scanf("%d",&K);
  a[1]=7%K;
  for(int i=2;i<=K;i++)a[i]=(a[i-1]*10+7)%K;
  
  for(int i=1;i<=K;i++)if(a[i]==0){
    printf("%d\n",i);
    return 0;
  }
  printf("-1\n");
}

posted:
last update: