USACO 1.6.2 Prime Palindromes

题解

这道题有点意思,原题给了提示的,没看前我是先算质数再做回文判断,
看了提示豁然开朗,先列回文数可以减少质素判断,明显是更明智的做法。
这题思路很清晰的,难点在如何不重不漏构造回文数,构造不同长度的回文数
似乎有点困难,但是固定长度的回文数是不是更好造呢,我们不妨设构造n位长回文函数为deal(n),
只要将其复用就可以解决问题,详见代码。


代码

/*
PROG:pprime
ID:imking022
LANG:C++
 */
#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;

const int maxx = 10;

int a,b;
int cot[maxx];

bool isprm(int num){// 质数判断
    for(int i=2;i*i<=num;i++){
        if(num%i == 0) return false;
    }
    return true;
}

bool acc(int n){ // 手动加一
    int k,p;
    k = (n%2 == 1 ? (n+1) /2 : n/2);
    if(cot[k]!=9) cot[k]++;
    else{// 遇9进位
        p = k;
        while(cot[k]==9) k--;

        if(k==0) return false;
        else if(k==1) cot[k]+=2;
        else cot[k]++;

        for(int j=k+1;j<=p;j++) cot[j] = 0;
    }
    return true;
}
void ini(int n){// 预处理 cot = 01000....
    memset(cot,0,sizeof(int)*n);
    cot[1]=1;
}
void deal(int n){
    if(n<2) return;

    // init cot
    ini(n);
    int num,base,k,p;
    p = (n%2 == 1 ? (n+1) /2 : n/2);

    //main loop
    while(true){
        num = 0;
        for(int i=p; i>0;i--){// 因为是回文数字确定一半即可
            num+=cot[i];
            if(i!=1) num*=10;
        }

        base = 1;
        for(int i=0;i< n/2 ; i++){// 另一半加上来
            k = (num/base)%10;
            num += k * pow(10, n-(i+1));
            base *=10;
        }

        if(num>b) break;

        // judgement
        if(isprm(num) && num>=a)
            cout<<num<<endl;

        // acc 加一
        if(! acc(n) ) break;
    }
}

int main(void){
    freopen("pprime.in","r",stdin);
    freopen("pprime.out","w",stdout);

    cin>>a>>b;
    int ca,cb,la,lb;// cal for the lengths of a and b
    ca = a,cb = b;
    la=lb=0;
    while(ca>0){
        ca/=10;
        la++;
    }
    while(cb>0){
        cb/=10;
        lb++;
    }

    for(int k=la;k<=lb;k++){
        if(k==1){
            for(int i=a;i<10;i++) if(isprm(i)) cout<<i<<endl;
        }
        else
            deal(k);// deal with each length
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/smmyy022/article/details/80293426