給定整數 n (1 ≤ n ≤ 10000),求最小的正整數 k,使得由 k 個 1 組成的數字(即 111...1,共 k 位)能被 n 整除。輸出 k。
設 R(k) = (10^k - 1) / 9 為 k 個 1 組成的數。
遞推關係:
R(1) = 1
R(k) = R(k-1) * 10 + 1
僅關心模 n 餘數:
rem(1) = 1 % n
rem(k) = (rem(k-1) * 10 + 1) % n
當 rem(k) == 0 時,R(k) 能被 n 整除,k 即為答案。
{0, 1, ..., n-1} 只有 n 種可能。n+1 步必出現重複餘數。0 未出現,序列進入循環,但 R(k) 嚴格遞增,不可能循環 → 矛盾。0 必出現,解存在且 k ≤ n。#include <cstdio>
int main() {
int n;
while (~scanf("%d", &n)) {
int rem = 1 % n, k = 1;
while (rem != 0) {
rem = (rem * 10 + 1) % n;
++k;
}
printf("%d\n", k);
}
return 0;
}
O(k),最壞 O(n),n ≤ 10000 瞬間通過。O(1),僅需兩個整數變量。| n | 最小全 1 倍數 | k |
|---|---|---|
| 3 | 111 | 3 |
| 7 | 111111 | 6 |
| 9 | 111111111 | 9 |
| 17 | 1111111111111111 (16 個 1) | 16 |
rem = 1%1 = 0,循環不進入,直接輸出 k=1,正確。111...1 大整數,n=9999 時 k 可達數千位,超出任意基本類型。只做模運算。while (~scanf(...)) 處理 EOF,UVA 標準輸入格式。求解 10^k ≡ 1 (mod 9n) 且 gcd(10, 9n)=1。
此即 乘法階 問題,k 為 10 模 9n 的階。本題遞推法本質上是暴力求階,因 n 小足夠高效。