This question is amazing. The meaning of the question is to give a number L. If there is a number K that makes L * K = 888 ..., ask 888... the minimum length. If such K does not exist, the output is 0.
I don't have any idea. After a few days, the number theory killed me and I had to find the answer.
I see a reliable method. First, 888... = 111... * 8 = (10 ^ 0 + 10 ^ 1 +... + 10 ^ m-1) * 8 = (10 ^ m-1)/9*8, PS: m represents 888....
Well, it turned into an index. Now there are 8*(10 ^ m-1)/9 = K * L, and the smallest m is the answer we asked.
Method 1:
=> 8*(10 ^ m-1) = 9 * k * L
=> 8/d * (10 ^ m-1) = 9 * k * L/d, d = gcd (8, 9L)
=> 10 ^ M-1 = 0% 9 * L/gcd (8, 9L) = 0% 9 * L/gcd (8, L), (due to gcd (8/d, 9L/d) = 1, then 10 ^ S-1 must be a multiple of 9 * L/d ).
10 ^ m = 1% 9 * L/gcd (8, L)
Method 2:
=> 8*(10 ^ m-1)/9 = 0% L
=> 8*(10 ^ m-1) = 0% 9 * L (for example, if x/9 = k * n, then x = 9 * k * n, apparently true)
=> 10 ^ M-1 = 0% 9 * L/gcd (9 * L, 8), if d = gcd (9 * L, 8 ), so there are 8/d * (10 ^ m-1) = k * 9 * L/d, because 8/d cannot be 9 * L/d
So M-1 must be a multiple of 9 * L/d, so 10 ^ M-1 = 0% 9 * L/gcd (9 * L, 8), =>, 10 ^ m-1 = 0% 9 * L/gcd (L, 8 ),
(Because gcd (9, 8) = 1 ).
10 ^ m = 1% 9 * L/gcd (8, L)
Now, both methods are available, 10 ^ m = 1% 9 * L/gcd (8, L ).
So how can we solve this problem? This is the Euler's theorem. So that p = 9 * L/gcd (8, L), then 10 ^ m = 1% p. According to Euler's theorem, all the values in Z * p
The number a must be a ^ euler (p) = 1% p. Then, 10 must be included in the multiplication group of p. If 10 is not in Z * p, 10 ^ m = 2 ^ m * 5 ^ m.
And 10 and p have announcement factor 2 or 5, so p = 2 * k or p = 5 * k, 2 ^ m = 0% p or 5 ^ m = 0% p, then 10 ^ m will never be 1% p.
To sum up, to satisfy the expression a ^ m = 1% p, it must be gcd (p, a) = 1, that is, a must be a number in the multiplication group of p.
The problem now is to find the smallest m. the euler's theorem knows that a ^ euler (p) = 1% p, and then m starts a loop. However, m may be smaller. For example, we now know the smallest m
If it is min, a ^ min = 1% p will exist. To meet a ^ euler (p) = 1% p, a ^ euler (p) will certainly be able to be changed to (a ^ min) ^ k. I don't know how much k is, of course.
You can also find out. Then min is a factor of euler (p), and it is the smallest factor that satisfies a ^ min = 1% p.
Now we can find the minimum factor min that satisfies the formula a ^ min = 1% p by enumerating the euler (p) factors to solve this problem.
Note that finding a ^ m % p must be based on the method described above in the introduction to algorithms. The complexity of O (32) or O (64), and a * B % m needs to be simulated by yourself, because a * B may overflow.
The Code is as follows. It seems that the code can be accelerated through other improvements.
# Include <stdio. h>
# Include <math. h>
# Include <algorithm>
# Include <string. h>
Using namespace std;
Typedef long INT;
// 10 ^ m = 1% (9 * L/gcd (8, L), minimum m
// P = 9 * L/gcd (8, L)
// Gcd (p, 10 )! = 1 p has a factor of 2 or 5, 2 ^ m = 1% p or
// 5 ^ m = 1% p no solution, no solution in the original format
// If (p) prime number, m = euler (p) = p-1
// Otherwise, m must be the minimum factor that satisfies the equation of euler (p ).
// Because (10 ^ m) ^ n = 10 ^ euler (p) = 1% p
INT gcd (INT a, INT B)
{
If (a <B) swap (a, B );
While (B)
{
INT t =;
A = B;
B = t % B;
}
Return;
}
INT Euler (INT nN)
{
INT nAns = 1;
INT nMax = sqrt (double) nN) + 1;
For (INT I = 2; I <= nMax; ++ I)
{
If (nN % I = 0)
{
NAns * = I-1;
NN/= I;
While (nN % I = 0)
{
NAns * = I;
NN/= I;
}
}
}
If (nN! = 1) nAns * = nN-1;
Return nAns;
}
INT MultMod (INT a, INT B, INT mod)
{
INT ans = 0;
While (B)
{
If (B & 1)
{
Ans = (ans + a) % mod;
}
A = (2 * a) % mod;
B> = 1;
}
Return ans;
}
INT ExpMod (INT base, INT exp, INT mod)
{
INT ans = 1;
Base % = mod;
While (exp)
{
If (exp & 1)
{
Ans = MultMod (ans, base, mod );
}
Base = MultMod (base, base, mod );
Exp> = 1;
}
Return ans % mod;
}
INT GetAns (INT p)
{
INT u = Euler (p );
INT nMax = sqrt (double) u) + 1;
INT nAns = u;
For (INT I = 1; I <= nMax; ++ I)
{
If (u % I = 0)
{
If (ExpMod (10, I, p) = 1)
{
NAns = I;
Break;
}
If (ExpMod (10, u/I, p) = 1)
{
NAns = min (nAns, u/I );
}
}
}
Return nAns;
}
Int main ()
{
INT nL;
INT nCase = 1;
While (scanf ("% I64d", & nL), nL)
{
INT p = 9 * nL/gcd (nL, 8 );
If (gcd (p, 10 )! = 1)
{
Printf ("Case % I64d: 0 \ n", nCase ++ );
Continue;
}
Printf ("Case % I64d: % I64d \ n", nCase ++, GetAns (p ));
}
Return 0;