答案范围是1-2e8,找出该范围内所有符合回文状态的质数即可计算答案
首先遍历1-1e5中的所有数,以此数为基数创建回文数,如由12可得三个回文数(212,2112,21012),复杂度为1e5
然后判断该数是不是质数
判断过程为:先找出小于sqrt(2e8)的所有的质数(即代码中的数组pri),如果2e8范围内的某个数不是质数,则一定可以在pri中找到它的一个因子,相反,若找不到,则该数就是一个质数,pri大小为1700左右
则总复杂度1700*1e5,算上其他限制,总计算次数并没有这么大
typedef long long ll;
const int maxn = 14150;
const int maxm = 1e5+7;
class Solution {
public:
int priMid[maxn];
int pri[maxn],priLen;
ll F[20];
int ansL[maxm*2],ansLen;
void init(){
memset(priMid,0,sizeof(priMid));
priLen=0;
for(int i=2;i<maxn;i++){
for(int j=i*i;j<maxn;j+=i)priMid[j]=1;
if(!priMid[i]){
pri[priLen++]=i;
}
}
F[0]=1;
for(int i=1;i<20;i++)F[i]=F[i-1]*10;
}
ll get1(int& x){
if(x%10==0)return 0;
ll ins=0,num=x;
while(num>0){
num/=10;
ins++;
}
num=x;
for(int i=0;i<ins;i++){
num+=F[ins*2-1-i]*(x/F[i]%10);
}
return num;
}
ll get2(int& x){
if(x%10==0)return 0;
ll ins=0,num=x;
while(num>0){
num/=10;
ins++;
}
num=x;
for(int i=0;i<ins-1;i++){
num+=F[ins*2-2-i]*(x/F[i]%10);
}
return num;
}
ll get3(int& x){
if(x%10==0)return 0;
ll ins=0,num=x;
while(num>0){
num/=10;
ins++;
}
if(ins>4)return 0;
num=x;
for(int i=0;i<ins;i++){
num+=F[ins*2-i]*(x/F[i]%10);
}
return num;
}
bool isPri(int x){
if(x==2)return true;
for(int i=0;i<priLen;i++){
if(x%pri[i]==0)return false;
if(pri[i]*pri[i]>x)break;
}
return true;
}
int primePalindrome(int N) {
init();
ansLen=1;
ansL[0]=2;
for(int i=1;i<maxm;i+=2){
ll x=get1(i);
ll y=get2(i);
ll z=get3(i);
if(x>1 && x<2e8 && isPri(x))ansL[ansLen++]=x;
if(y>1 && y<2e8 && isPri(y))ansL[ansLen++]=y;
if(z>1 && z<2e8 && isPri(z))ansL[ansLen++]=z;
}
sort(ansL,ansL+ansLen);
int ans = lower_bound(ansL,ansL+ansLen,N)-ansL;
return ansL[ans];
}
};