1. 程式人生 > 實用技巧 >P1217 [USACO1.5]迴文質數 Prime Palindromes

P1217 [USACO1.5]迴文質數 Prime Palindromes

題目連結:https://www.luogu.com.cn/problem/P1217

題目分析:

  看著很簡單,以為用線性篩篩質數時間複雜度O(n)足夠了,但是超時了

超時程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100000010;
 4 int primes[N], cnt;
 5 bool st[N];
 6 void get_primes(int n) { //線性篩篩質數 
 7     for (int i = 2; i <= n; i++) { 
 8         if (!st[i]) { 
9 primes[cnt++] = i; 10 } 11 for (int j = 0; primes[j] <= n / i; j++) { 12 st[primes[j] * i] = true; 13 if (i % primes[j] == 0) { 14 break; 15 } 16 } 17 } 18 } 19 bool check(int x) { //判斷是否是迴文數 20 //思路:就是把一個數倒過來,再判斷倒過來的數是否和原來的數相等
21 int y = x, num = 0; //int y = x, 防止x被改變 22 while (y != 0) { 23 num = num * 10 + y % 10; 24 y /= 10; 25 } 26 if (num == x) { 27 return true; 28 } else { 29 return false; 30 } 31 } 32 int main() { 33 ios::sync_with_stdio(false); 34 cin.tie(0);
35 cout.tie(0); 36 int a, b; 37 cin >> a >> b; 38 get_primes(b); 39 for (int i = a; i <= b; i++) { 40 41 if (check(i) && !st[i]) { //是迴文數且是質數的話 42 cout << i << endl; 43 } 44 } 45 return 0; 46 }

然後就新學了一個數學知識:偶數位數迴文數(除11)必定不是質數,所以只要執行到9999999 。因為10000000~99999999都是偶數位,

如果其中存在迴文數的話,那麼一定不是質數。100000000又不是迴文數,所以只篩5 ~ 9999999中的質數就可以了。

這個數學性質就是:除 11 外的偶數位迴文數,都能被 11 整除

證明:一個整數如果奇數位的數字和等於偶數位的數字和,則其能被11整除。如果一個迴文數的長度為偶數,則顯然有這個特徵。

即:所有偶數位數的迴文數都能被11整除。這樣所有偶數位數的迴文數就都不是質數了,因為有11這個約數了

AC程式碼:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100000010;
 4 int primes[N], cnt;
 5 bool st[N];
 6 void get_primes(int n) { //線性篩篩質數 
 7     for (int i = 2; i <= n; i++) { 
 8         if (!st[i]) { 
 9             primes[cnt++] = i;
10         }
11         for (int j = 0; primes[j] <= n / i; j++) {
12             st[primes[j] * i] = true;
13             if (i % primes[j] == 0) { 
14                 break;
15             }
16         }
17     }
18 }
19 bool check(int x) { //判斷是否是迴文數
20     //思路:就是把一個數倒過來,再判斷倒過來的數是否和原來的數相等 
21     int y = x, num = 0; //int y = x, 防止x被改變
22     while (y != 0) {
23         num = num * 10 + y % 10; 
24         y /= 10;
25     } 
26     if (num == x) {
27         return true;
28     } else {
29         return false;
30     }
31 }
32 int main() {
33     ios::sync_with_stdio(false);
34     cin.tie(0);
35     cout.tie(0);
36     int a, b;
37     cin >> a >> b;
38     if (b >= 10000000) { //注意此處 
39         b = 9999999;
40     } 
41     get_primes(b);
42     for (int i = a; i <= b; i++) {
43         if (i >= 10000000) { //注意此處 
44             break;
45         }
46         if (check(i) && !st[i]) { //是迴文數且是質數的話 
47             cout << i << endl;
48         }
49     }
50     return 0;
51 }