Poj 3696 The Luckiest number

Source: Internet
Author: User

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;


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.