P1217 [USACO1.5]回文質數 Prime Palindromes(求100000000內的回文素數)


 

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

題目描述

因為151既是一個質數又是一個回文數(從左到右和從右到左是看一樣的),所以 151 是回文質數。

寫一個程序來找出范圍[a,b](5 <= a < b <= 100,000,000)( 一億)間的所有回文質數;

輸入輸出格式

輸入格式:

 

第 1 行: 二個整數 a 和 b .

 

輸出格式:

 

輸出一個回文質數的列表,一行一個。

 

輸入輸出樣例

輸入樣例#1:
5 500
輸出樣例#1:
5
7
11
101
131
151
181
191
313
353
373
383

說明

Hint 1: Generate the palindromes and see if they are prime.

提示 1: 找出所有的回文數再判斷它們是不是質數(素數).

Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.

提示 2: 要產生正確的回文數,你可能需要幾個像下面這樣的循環。

題目翻譯來自NOCOW。

USACO Training Section 1.5

產生長度為5的回文數:

for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇數才會是素數

     for (d2 = 0; d2 <= 9; d2++) { for (d3 = 0; d3 <= 9; d3++) { palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(處理回文數...) } } }

分析

求回文素數,如果枚舉所有的數,會很浪費時間,所以可以先構造出回文數,然后判斷是不是素數即可,

  • 除11不存在偶數位的回文數是素數,因為該回文數能被11整除,也就說明大於11的滿足條件的回文數是奇數位,以中間數為對稱軸。
  • 因大於2的素數都是奇數,故在奇數位回文數中,首位為2、4、6、8的數均不是素數。首位是它們,根據回文數的性質,末尾也是他們。
  • 因5的任何倍數末尾為5,故在奇數位回文數中,首位為5的數均不是素數。

滿足以上條件,制造回文數。

因為回文數呈現對稱,所以構造時做多5位(一共99999個數),減去偶數一半,還剩不到5萬個,剩下的數中首位為0、2、4、5、6、8的數均不滿足條件,回文數最多為2W個。

構造出回文數后,在判斷是否滿足素數。

code

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int l,r,now = 2;
 8 
 9 int Creatpalindrome(int n)//構造回文數 
10 {
11     if (n<10)//小於10的會問素數只有2,3,5,7,兩位的只有11 
12     {
13         switch(n)
14         {
15             case 2:now=3;return 2;//now遞進的,下一次調用函數時就會進行下一條語句 
16             case 3:now=5;return 3;
17             case 5:now=7;return 5;
18             case 7:now=9;return 7;
19             case 9:now=10;return 11;
20         }
21     }
22     
23     int wn = (int)(log(n*1.0)/log(10*1.0));//位數-1,以中間位對稱軸 
24     int gn = n/(int)(pow(10*1.0,wn));//最高位是什么 
25     int ret = 0;
26     //最高位2,4,6,8,5都不滿足條件,但它們+1就滿足,所以它們的最高位+1 
27     switch (gn)
28     {
29         case 2:
30         case 4:
31         case 6:
32         case 8:
33             now = (gn+1)*(int)pow(10*1.0,wn);//最高位+1后的數 
34             ret = now*(int)pow(10*1.0,wn)+(gn+1);//最后一位數要和最高位一樣 
35             ++now;
36             return ret;
37         case 5:
38             now = 7*(int)pow(10*1.0,wn);//最高位是5就將它變成7 
39             ret = now*(int)pow(10*1.0,wn)+7;
40             ++now;
41             return ret;
42     }
43     //最高位滿足條件 
44     int sumn = 0;
45     //記錄n的前n-1位逆序和,比如12345的逆序和為4321,所以n 
46     ret = n*(int)pow(10*1.0,wn);
47     n /= 10;
48     
49     while (n)
50     {
51         sumn = sumn*10+n%10;
52         n /= 10;
53     }
54     ++now;
55     return ret+sumn;    
56 }
57 bool Isprime(int x)
58 {
59     for (int i=3; i*i<=x; i+=2)
60     {
61         if (x%i==0)
62         return false ;
63     }
64     return true;
65 }
66 int main()
67 {
68     cin>>l>>r;
69     for (int i=l; i<=r; )
70     {
71         i = Creatpalindrome(now);
72         if (i>=l&&i<=r&&Isprime(i))
73         {
74             cout<<i<<endl;
75         }
76     }
77     return 0;
78 }

參考博客http://blog.csdn.net/arvonzhang/article/details/8565515


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM