1. 程式人生 > >題解報告:hdu 1431 素數回文

題解報告:hdu 1431 素數回文

ble 提交 標記 false 結果 its 無奈 rime using

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1431

解題思路:這道題交了10次才A掉(怪菜雞太弱。。。),剛開始是直接用歐拉篩算法模板+簡單的判斷回文,結果顯示超內存。。。歐拉篩的時間復雜度可是O(n)線性時間。。。這樣我重新解讀題目,其最大範圍是10的8次方,但多次小修改提交後還是超內存。於是直接用了暴力,結果顯示超時,無奈將這兩個算法結合在一起,結果還是顯示超時。當看到題解之後才明白,歐拉篩(埃氏篩也一樣)裏面用到int數組開辟的空間比較占內存,這就是超內存的原因,而單獨用bool類型來判斷的話就剛剛好,因為它占1個字節。超時就是算法不高級,這個不用說了吧。還有在這10的8次方內最大的回文素數是9989899(7位數),於是只需枚舉到9999999(7位數),這樣就節省了一大堆時間,也就基本不會超時了。A這道題的解法就是先單獨寫一個判斷回文的函數;再判斷素數時先篩掉偶數,再從奇數中進行篩掉一些合數,這樣就不會用到int數組,也不會涉及到內存超過限制的原因了。好了,上代碼吧!

AC代碼:

 1 #include<bits/stdc++.h>
 2 #define maxn 9999999
 3 using namespace std;
 4 bool prime1[maxn];
 5 int cnt,a,b;//標記素數
 6 bool prime2(int n)//判斷素數是否回文
 7 {
 8     int sum=0,tmp=n;
 9     while(tmp){
10         sum=sum*10+tmp%10;
11         tmp/=10;
12     }
13     if(sum==n)return true;
14     else
return false; 15 } 16 int main() 17 { 18 memset(prime1,true,sizeof(prime1)); 19 prime1[0]=prime1[1]=false; 20 for(int i=4;i<maxn;i+=2)prime1[i]=false;//先篩掉偶數 21 for(int i=3;i<=3163;i+=2){//再在剩下奇數中尋找,maxn的開方是3162多一點,這裏取3163 22 if(prime1[i]){//當前的奇數是素數 23 for(int j=i*i;j<maxn;j+=2
*i)prime1[j]=false;//枚舉從平方開始後面的奇數 24 } 25 } 26 while(cin>>a>>b){ 27 for(int i=a;i<=b;i++){ 28 if(i>=maxn)continue;//超過範圍的最大素數則繼續循環 29 if(prime2(i)&&prime1[i])cout<<i<<endl;//先判斷是否是回文數,再判斷是不是素數,這樣的話就不會超時 30 } 31 cout<<endl; 32 } 33 return 0; 34 }

題解報告:hdu 1431 素數回文