leetcode 866. Prime Palindrome

答案范围是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];
    }
};

猜你喜欢

转载自blog.csdn.net/jfnfjivkdnfjf/article/details/81036074
今日推荐