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, 0, sizeof(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
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, 0, sizeof(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