给定一个正整数 L
,问至少多少个 8 连在一起组成的正整数可以是 L 的倍数
N 个 8 组成的自然数是 (10 ^ N - 1) / 9 * 8。原题即为求最小的 N 满足 (10 ^ N - 1) / 9 * 8 = k * L。设 t = gcd(L, 8)。上式即为 8(10 ^ N - 1 ) / t = 9kL。显然 8/t, 9L/t 都是整数,且 gcd(8/t, 9L/t)=1。所以 (9L/t) | (10 ^ N - 1)。也就是 10^N = 1(mod 9L/t)。也就是 10 关于 9L/t 的阶。于是 N 是 φ(9L/t)的约数。检查所有约数即可。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 50000;
typedef long long LL;
LL n, d[MAX_N << 1], cnt = 0;
LL a;
int gcd(int x, int y)
{
if(!y) return x;
return gcd(y, x % y);
}
LL mult(LL a, LL b, LL p)
{
LL ret = 0;
while (b)
{
if (b & 1)
ret = (ret + a) % p;
a = 2 * a % p;
b >>= 1;
}
return ret;
}
LL power(LL x, LL n, LL p)
{
LL ret = 1;
x %= p;
while (n)
{
if (n & 1)
ret = mult(ret, x, p);
x = mult(x, x, p);
n >>= 1;
}
return ret;
}
void doit()
{
int g = gcd(8, n);
a = (LL)(9 * (n / g));
LL f = 1, t = a;
for(LL i = 2; i * i<= a; i ++){
if (t % i == 0){
f *= (i-1); t /= i;
while(t%i ==0){
f *= i;
t /= i;
}
}
if (t == 1) break;
}
if (t > 1) f *= (t-1); //计算phi
for (LL i = 1; i * i <= f; i ++){
if (f % i == 0) d[++ cnt] = i, d[++ cnt] = f / i;
}
sort(d + 1, d + cnt + 1); // 计算phi的因子
bool ok = 0;
for (int i = 1; i <= cnt; i ++){
//printf("%lld ", power(10, d[i], a));
if(power(10, d[i], a) == 1) { ok = 1; printf("%lld\n", d[i]); break; }
}
if (!ok) printf("0\n");
}
int main()
{
int tot = 0;
while(scanf("%lld", &n) != EOF){
if (n == 0) break;
printf("Case %d: ", ++ tot);
cnt = 0;
doit();
}
return 0;
}