Question: Give a number n and find a multiple of them. Each digit of this number is 8. Find the smallest digit. Otherwise, 0 is output.
It is actually a very interesting number theory, and the code is not very difficult.
But it is a pity that not ~~~~~~ Bytes
8888888 can certainly be written as 8*(10 ^ k-1)/9 = m * n, n is the original number, k is the number of digits.
8*(10 ^ k-1) = 9 * n * m, so that r = gcd (8, n)
Then 8/r * (10 ^ k-1) = 9 * n/r * m. To make 8/r * (10 ^ k-1) a multiple of 9 * n/r, and the interconnectivity between 8/r and 9 * n/r, so 10 ^ k-1 = 0 (MOD 9 * n/r)
10 ^ k = 1 (MOD 9 * n/r ). According to Euler's theorem, if 10 and 9 * n/r are mutually qualitative, 10 ^ phi (9 * n/r) = 1 (mod (9 * n/r ).
Therefore, no solution is to avoid mutual quality.
Then, phi (9 * n/r) is decomposed into quality factors to obtain all the approximate numbers, and then the equality is determined from an ascending point.
Note that the maximum range of 9 * n/r is 1.8*10 ^ 10. Due to overflow, I still use high-precision analog multiplication.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cmath>
# Include <vector>
# Define N 80005
# Define maxn150005
# Define LL long
# Define pb (a) push_back ()
Using namespace std;
Bool flag [N] = {0 };
Int cnt = 0, prime [N];
LL gcd (LL a, LL B ){
Return B = 0? A: gcd (B, a % B );
}
Void Prime (){
For (int I = 2; I <N; I ++ ){
If (flag [I]) continue;
Prime [cnt ++] = I;
For (int j = 2; j * I <N; j ++)
Flag [I * j] = true;
}
}
LL get_eular (LL n ){
LL ret = 1;
For (int I = 0; I <cnt & prime [I] * prime [I] <= n; I ++ ){
If (n % prime [I] = 0 ){
Ret * = prime [I]-1;
N/= prime [I];
While (n % prime [I] = 0 ){
N/= prime [I];
Ret * = prime [I];
}
}
}
If (n> 1) ret * = n-1;
Return ret;
}
LL fac [N] [2], tot;
Void Split (LL n ){
Tot = 0;
For (int I = 0; I <cnt & prime [I] * prime [I] <= n; I ++ ){
If (n % prime [I] = 0 ){
Fac [tot] [0] = prime [I];
Fac [tot] [1] = 0;
While (n % prime [I] = 0 ){
N/= prime [I];
Fac [tot] [1] ++;
}
Tot ++;
}
}
If (n> 1) {fac [tot] [0] = n; fac [tot ++] [1] = 1 ;}
}
Vector <LL> fact;
Void dfs (int idx, LL num ){
If (idx> = tot ){
Fact. pb (num );
Return;
}
LL tmp = 1;
For (int I = 0; I <= fac [idx] [1]; I ++, tmp * = fac [idx] [0])
Dfs (idx + 1, num * tmp );
}
LL MultMod (LL a, LL B, LL MOD ){
A % = MOD;
B % = MOD;
LL ret = 0;
While (B ){
If (B & 1 ){
Ret + =;
If (ret> = MOD) ret-= MOD;
}
A = a <1;
If (a> = MOD) a-= MOD;
B = B> 1;
}
Return ret;
}
LL PowMod (LL a, LL B, LL MOD ){
LL ret = 1;
While (B ){
If (B & 1) ret = MultMod (ret, a, MOD );
A = MultMod (a, a, MOD );
B> = 1;
}
Return ret;
}
Int main (){
LL n;
Int cas = 0;
Prime ();
While (scanf ("% I64d", & n )! = EOF & n ){
LL p = (LL) 9 * n/gcd (8, n );
Printf ("Case % d:", ++ cas );
If (gcd (10, p )! = 1 ){
Printf ("0 \ n ");
Continue;
}
LL phi = get_eular (p );
Split (phi );
Fact. clear ();
Dfs (0, 1 );
Sort (fact. begin (), fact. end ());
For (int I = 0; I <fact. size (); I ++ ){
If (PowMod (10, fact [I], p) = 1 ){
Printf ("% I64d \ n", fact [I]);
Break;
}
}
}
Return 0;
}