洛谷 P1217:[USACO1.5] 回文质数 Prime Palindromes

【题目来源】
https://www.luogu.com.cn/problem/P1217

【题目描述】
因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。
写一个程序来找出范围 [a,b](
5≤a<b≤100,000,000)(一亿)间的所有回文质数。

【输入格式】
第一行输入两个正整数 a 和 b。​​​​​​​

【输出格式】
输出一个回文质数的列表,一行一个。​​​​​​​

【输入样例】
5 500​​​​​​​

【输出样例】
5
7
11
101
131
151
181
191
313
353
373
383

【算法分析】
● 如下判断素数的经典代码,当 n 较大时(如
1e7),会非常耗时‌,最终导致 TLE。

bool isPrime(int n) {
    if(n<2) return false;
    for(int i=2; i<=sqrt(n); i++) {
        if(n%i==0) return false;
    }
    return true;
}

本题问题规模达到 1e8,采用如上素数的经典代码必然会导致部分样例 TLE。好在回文质数问题的数据规模限制在 ≤7 位,故可据此进行优化,避免 TLE。

● 在算法竞赛或编程问题中,若需处理回文质数,一种方法是直接将数的范围限制在 ≤7 位,避免无效计算‌。因为
不存在大于 10⁷ 的回文质数,最大回文质数为 9989899。另一种方法为欧拉筛法(又称线性筛法)结合回文判断求解。本题代码采用第一种方法。

● 欧拉筛法(又称线性筛法)
欧拉筛法(又称线性筛法)是一种高效筛选素数的算法,其核心特点是保证每个合数仅被其最小质因子筛除一次,从而实现 O(n) 的时间复杂度‌。欧拉筛法适用于大规模素数筛选(如 1e7 以上)‌的场景。欧拉筛法 C++ 代码如下所示。

#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6+5;
int prime[maxn];
bool st[maxn];

int euler_sieve(int n) {
    int cnt=0;
    memset(prime,0,sizeof(prime));
    memset(st,0,sizeof(st));
    for(int i=2; i<=n; i++) {
        if(!st[i]) prime[cnt++]=i;
        for(int j=0; j<cnt && i*prime[j]<=n; j++) {
            st[i*prime[j]]=true;
            if(i%prime[j]==0) break;
        }
    }
    return cnt;
}

int main() {
    int n;
    cin>>n;
    cout<<euler_sieve(n)<<endl;
    return 0;
}

/*
in:8
out:4
*/

此代码适用于:https://www.acwing.com/problem/content/870/

【算法代码】

#include <bits/stdc++.h>
using namespace std;

bool isPrime(int n) {
    if(n<2) return false;
    for(int i=2; i<=sqrt(n); i++) {
        if(n%i==0) return false;
    }
    return true;
}

bool isHW(int x) {
    int t=0;
    int y=x;
    while(y) {
        t=t*10+y%10;
        y/=10;
    }
    return t==x;
}

int main() {
    int le,ri;
    cin>>le>>ri;
    if(ri>=1e7) ri=9999999;
    for(int i=le; i<=ri; i++) {
        if(isHW(i) && isPrime(i)) {
            cout<<i<<endl;
        }
    }

    return 0;
}

/*
in:
5 500

out:
5
7
11
101
131
151
181
191
313
353
373
383
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/148121301
https://blog.csdn.net/hnjzsyjyj/article/details/149547149

https://www.acwing.com/problem/content/870/
https://www.acwing.com/file_system/file/content/whole/index/content/3273/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值