题目链接: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 }