解题思路(70分):
1.由于数据量比较大,所以采用埃式筛选法来筛选素数
2.确定最小值和最大值,min=pow(10,n-1),max=pow(10,n)
3.依次枚举,如果是回文数并且是素数的话,计数器累加,存入数组
4.输出计数器和各个回文素数
#include<bits/stdc++.h>
using namespace std;
bool a[1000000005];//埃式筛选法求素数
int num[10000000];//存回文素数数组
bool check(int x)//判断是否为回文数
{
int m=x,count=0;
while(m!=0)
{
count=count*10+m%10;
m=m/10;
}
if(count==x)
return true;
else
return false;
}
int main()
{
int n,sum=0,k=0;
a[1]=1;
cin>>n;
int min=pow(10,n-1);//确定最小值
int max=pow(10,n);//确定最大值
for(int i=2;i<=max;i++)
{
if(a[i]==0)
for(int j=2;j*i<=max;j++)
a[i*j]=1;
}//埃式筛选法求素数
for(int i=min;i<max;i++)
{
if(check(i)&&a[i]==0)//如果这个数是质数并且是回文数
{
sum++;//计数器累加
num[++k]=i;//将该数存入数组
}
}
cout<<sum<<endl;//输出回文素数的个数
for(int i=1;i<=k;i++)//依次输出这些数
cout<<num[i]<<" ";
return 0;
}
优化思路(100分):
1.当数据量比较大的时候,很明显挨个判断是否为回文数也会超时,该如何优化呢?
重点:在素数领域有一个性质,偶数位数的除了11以外全部不是回文素数
2.那么只需要对n为1和2的时候进行特判,n为1的时候,回文素数有4个分别是2,3,5,7,当n为2的时候,只有1个回文素数是11
3.当输入的n为偶数的时候,直接输出0即可
4.当n为奇数的时候,为了缩短时间,可以采用构造回文数的方法,构造回文数中,如果前n/2-1位确定了,那么可以使用累加版数位分离的方法补齐另一半,然后再对构造好的回文数判断是否是素数,即可缩短时间
#include<bits/stdc++.h>
using namespace std;
long long a[50000];
bool check1(int x)//检验是否为素数
{
for(int i=2;i<=sqrt(x);i++)
if(x%i==0)
return false;
return true;
}
int build(int x)//构造回文数,例如123返回了12321
{
int temp=x;
x=x/10;
while(x!=0)
{
temp=temp*10+x%10;
x=x/10;
}
return temp;
}
int main()
{
int n,k=0;
cin>>n;
if(n==1)//对于1和2进行特判
{
cout<<4<<endl<<2<<" "<<3<<" "<<5<<" "<<7;
return 0;
}
else if(n==2)
{
cout<<1<<endl<<11;
return 0;
}
else if(n%2==0)//偶数位数的所有数都不是回文素数,11除外
{
cout<<0;
return 0;
}
else
{
int min=pow(10,(n+1)/2-1);
int max=min*10;
for(int i=min;i<max;i++)
{
int num=build(i);
if(check1(num))
a[++k]=num;
}
}
cout<<k<<endl;
for(int i=1;i<=k;i++)
cout<<a[i]<<" ";
return 0;
}