P1217 [USACO1.5]回文质数 Prime Palindromes(技巧+暴力枚举+线性筛)

技巧:就是偶数位的回文数字一定不是质数---------证明:奇数位之和sum1==偶数位之和sum2的数字可以被11整除。(11除外,这是一个坑点)

   最高位,最低位必须是 1, 3, 7, 9

暴力枚举:也就是说,直接枚举奇数位(1,3,5,7)就可以了。至于回文嘛,除去最高位和最低位,也最多是枚举3位数字,时间复杂度在10^3.不管怎么说还是暴力的起的。

线性筛:就是用于判断最后枚举的数字是不是质数的,注意,还是要把质数的范围取大一点。根据质数在后面越来越少的概率图,大家,可以随便定个范围。

    最开始,是筛的1000以内的质数,但是,错了很多,所以筛了10000以内的就过了。

ac代码:

#include<iostream>
using namespace std;
const int N = 1e4;
int prime[N], sum, r, l;
bool vis[N];
bool is_prime[N];
int a[] = { 1, 3, 7, 9 };
int kk[] = { 5, 7 ,11};
int Prime(int n = N){
    int cnt = 0;
    for (int i = 2; i <= n; ++i)
    {
        if (!vis[i]){
            prime[cnt++] = i;
            is_prime[i] = 1;
        }
        for (int j = 0; j < cnt&&i*prime[j] <= n; ++j)
        {
            vis[i*prime[j]] = 1;
            if (i%prime[j] == 0)break;
        }
    }
    return cnt;
}

bool f(int x){
    if (x < N)return is_prime[x];
    else{
        for (int i = 0; i < sum; ++i){
            if (x%prime[i] == 0)return 0;
        }
    }
    return 1;
}

void DFS(){
    int num;
    for (int i = 0; i <= 2;++i)
    if (kk[i] >= l&&kk[i] <= r)cout << kk[i] << endl;
    if (r / 100){
        for (int i = 0; i <= 3; ++i){
            for (int j = 0; j <= 9; ++j){
                num = a[i] * 100 + j * 10 + a[i];
                if (num>=l&&num<=r&&f(num))cout << num << endl;
            }
        }
    }
    if (r / 10000){
        for (int i = 0; i <= 3; ++i){
            for (int a1 = 0; a1 <= 9;++a1)
            for (int a2 = 0; a2 <= 9; ++a2){
                num = a[i] * 10000 + a1 * 1000 + a2 * 100 + a1 * 10 + a[i];
                if (num >= l&&num <= r&&f(num))cout << num << endl;
            }
        }
    }
    if (r / 1000000){
        for (int i = 0; i <= 3; ++i){
            for (int a1 = 0; a1 <= 9; ++a1)
            for (int a2 = 0; a2 <= 9; ++a2)
            for (int a3 = 0; a3 <= 9;++a3){
                num = a[i] * 1000000 + a1 * 100000 + a2 * 10000+a3*1000+a2*100 + a1 * 10 + a[i];
                if (num >= l&&num <= r&&f(num))cout << num << endl;
            }
        }
    }
}

int main(){
    sum = Prime();
    cin >> l >> r;
    DFS();
}

猜你喜欢

转载自www.cnblogs.com/ALINGMAOMAO/p/10657963.html