POJ 3696 The Luckiest number

POJ 3696 The Luckiest number

  1 /**/ /*
  2POJ 3696 The Luckiest number
  3
  4
  5----问题描述:
  6
  7Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his own lucky number L. Now he wants to construct his luckiest number which is the minimum among all positive integers that are a multiple of L and consist of only digit '8'.
  8
  9
 10----输入:
 11
 12The input consists of multiple test cases. Each test case contains exactly one line containing L(1 ≤ L ≤ 2,000,000,000).
 13
 14The last test case is followed by a line containing a zero.
 15
 16
 17----输出:
 18
 19For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the length of Bob's luckiest number. If Bob can't construct his luckiest number, print a zero.
 20
 21
 22----样例输入:
 23
 248
 2511
 2616
 270
 28
 29
 30----样例输出:
 31
 32Case 1: 1
 33Case 2: 2
 34Case 3: 0
 35
 36
 37----分析:
 38
 39(转自网上)
 40
 41题意:给一个数N(1<=N<=2000000000);问是否存在N的倍数M,且M的各个位全部由8组成,如果存在多个取最小的 M 并输出M由几个8组成。
 42
 43解题思路:因为M全部由8组成,即M=(10^x -1)*8/9=k*N;
 44
 45则    (10^x-1)*8/gcd(8,N)=9*k*N/gcd(8,N);
 46
 47令p=8/gcd(8,N);        q=9*N/gcd(8,N);    即    (10^x-1)*p=k*q;
 48
 49由于p和q互质,则(10^x-1)%q==0;
 50
 51根据同余定理可知,10^x ≡1(mod q)
 52
 53根据欧拉定理可知当gcd(a,b)==1时,a^φ(b)≡1(mod b);
 54
 55即可得出:当gcd(10,q)==1时    10^φ(q)≡1(mod q)   即通过枚举φ(q)的因子(最小因子)就能得出结果
 56
 57由于N比较大,因此采用long long 型。同时做一个素数表。
 58
 59在进行幂求模运算的时候可以采用快速幂的方法。
 60
 61由于在进行快速幂求模的时候数据会超出long long 的表示范围,因此要进行优化。
 62
 63
 64*/

 65
 66
 67 /**/ /**********************************************
 68版本一:
 69*/

 70
 71 #include  < iostream >
 72 #include  < cstdio >
 73 #include  < cstring >
 74
 75 using   namespace  std;
 76
 77 typedef  __int64  Lint;
 78
 79 #define   LP  45000
 80 int   nprime;
 81 Lint prime[ LP ];
 82
 83 #define   LF  128
 84 int   nf;
 85 Lint f[ LF ];
 86
 87 void  init_prime()  {
 88        int i, j;
 89        nprime = 0;
 90        memset( prime, 0sizeof(prime) );
 91        for ( i = 2; i < LP; ++i ) {
 92                if ( 0 == prime[ i ] ) {
 93                        prime[ nprime++ ] = i;
 94                        for ( j = i+i; j < LP; j += i ) {
 95                                prime[ j ] = 1;
 96                        }

 97                }

 98        }

 99}

100
101 void  calc_f( Lint n )  {
102        int i;
103        nf = 0;
104        for ( i = 0; (i < nprime)&&(prime[i]*prime[i] <= n); ++i ) {
105                while ( n % prime[ i ] == 0 ) {
106                        f[ nf++ ] = prime[ i ];
107                        n /= prime[ i ];
108                }

109        }

110        if ( 1 < n ) {
111                f[ nf++ ] = n;
112        }

113}

114
115 Lint gcd( Lint a, Lint b )  {
116        Lint t;
117        while ( 0 != b ) {
118                t = a;
119                a = b;
120                b = t % b;
121        }

122        return a;
123}

124          //  a * b % m
125 Lint mul_mod( Lint a, Lint b, Lint m )  {
126        Lint s = 0;
127        a %= m;
128        while ( 0 != b ) {
129                if ( 0 != (1 & b) ) {
130                        s += a;
131                        if ( s >= m ) {
132                                s -= m;
133                        }

134                }

135                a <<= 1;
136                if ( a >= m ) {
137                        a -= m;
138                }

139                b >>= 1;
140        }

141        return s;
142}

143          //  a ^ b % m
144 Lint pow_mod( Lint a, Lint b, Lint m )  {
145        Lint s = 1;
146        a %= m;
147        while ( 0 != b ) {
148                if ( 0 != (1 & b) ) {
149                        s = mul_mod( s, a, m );
150                }

151                a = mul_mod( a, a, m );
152                b >>= 1;
153        }

154        return s;
155}

156          //  欧拉
157 Lint phi( Lint n )  {
158        Lint s = n;
159        int i;
160        for ( i = 0; (i < nprime)&&(prime[i]*prime[i] <= n); ++i ) {
161                if ( n % prime[ i ] == 0 ) {
162                        s = s / prime[ i ] * (prime[ i ] - 1);
163                        do {
164                                n /= prime[ i ];
165                        }
 while ( n % prime[ i ] == 0 );
166                }

167        }

168        if ( 1 < n ) {
169                s = s / n * (n - 1);
170        }

171        return s;
172}

173
174 Lint solve( Lint n )  {
175        Lint m = 9 * n / gcd(8, n);
176        if ( 1 != gcd(10, m) ) {
177                return 0;
178        }

179
180        Lint ph = phi(m);
181        Lint s  = ph;
182        int  i;
183        bool down = true;
184        while ( down ) {
185                down = false;
186                calc_f(ph);
187                for ( i = 0; i < nf; ++i ) {
188                        if ( (pow_mod(10, ph/f[i], m) == 1&& (ph/f[i] < s) ) {
189                                s = ph / f[ i ];
190                                down = true;
191                        }

192                }

193                ph = s;
194        }

195        return s;
196}

197
198 int  main()  {
199        int td = 0, n;
200        init_prime();
201        while ( (1 == scanf("%d"&n)) && (0 < n) ) {
202                printf( "Case %d: %I64d\n"++td, solve(n) );
203        }

204        return 0;
205}

206

你可能感兴趣的:(POJ 3696 The Luckiest number)