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

        闲聊:因为今早上有小姐姐交流这个题目,刚刚才知道这个原来是顺序结构的题,啊哈,我是用欧拉筛做的,当时还做了好久(埃氏筛会超时的),顺序结构的题目观看->深入浅出

顺便复习一下欧拉筛->

输入:

5 500

输出:

5
7
11
101
131
151
181
191
313
353
373
383
 

题目分析:

1.顺序结构我就不讲了吧。

2.注意欧拉筛法,用vis数组标记合数的点(防止重复搜索),剩余的点与埃氏筛相似,都是标记质数的倍数->

复习一下埃氏筛的思想:从2开始,标记质数的倍数,加快筛选速度。(Onloglogn)

欧拉筛核心代码

void ola(int m) {
    memset(prime, 0, sizeof(prime));//常规填充
    memset(vis, 0, sizeof(vis));
    for (int i = 2; i <= m; i++) {
        if (vis[i] == 0) {//未被标记,即是素数才可以进入
            prime[cnt++] = i;用数组来升序记录素数的值的数组(只有素数的一个数组)
        }
        for (int j = 0; j < cnt && i * prime[j] <= m; j++) {
            vis[i * prime[j]] = 1;//标记,不是素数的点
            if (i % prime[j] == 0) {//重复的数不再筛选
                break;
            }
        }

    }
}

思考:为什么i%prime[j]==0之后就可以直接break呢?

        表示i不是最小质因数,为了确保合数只被最小质因数筛掉,所以break掉,从而降低复杂度。

欧拉筛的时间复杂度只有(On)

3.回文数判断不用说了吧(有点简单)。

4.还需要注意的一点是回文质数只能是奇数位:看看大佬们的解释->

//b<=10000000这个判断条件来自:除了11以外,一个数的位数是偶数的话,不可能为回文数素数。
    // 如果一个回文素数的位数是偶数,则它的奇数位上的数字和与偶数位上的数字和必然相等;
    // 根据数的整除性理论,容易判断这样的数肯定能被11整除,所以它就不可能是素数。

代码如下:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include<cmath>
#include<cstring>
#define maxn 10000008
using namespace std;
bool P[maxn];
int prime[maxn];
int vis[maxn];//标记数组
bool huiwen(int x) {
    int y = x;
    int num = 0;
    while (y != 0) {
        num = num * 10 + y % 10;
        y = y / 10;
    }
    if (num == x) {
        return true;
    }
    return false;
}

void ola(int m) {
    int cnt=0;//计数器
    if (m > 10000000) {
        m = 10000000;
    }
    memset(prime, 0, sizeof(prime));
    memset(vis, 0, sizeof(vis));
    for (int i = 2; i <= m; i++) {
        if (vis[i] == 0) {//未被标记,即是素数才可以进入
            prime[cnt++] = i; P[i] = 1;
        }
        for (int j = 0; j < cnt && i * prime[j] <= m; j++) {
            vis[i * prime[j]] = 1;//标记,不是素数的点
            if (i % prime[j] == 0) {//重复的数不再筛选
                break;
            }
        }

    }
}
int main()
{
    int n, m;
    cin >> n >> m;
    ola(m);
    for (int i = n; i <= m; i++) {
        if (i>10000000) {//八位数的时候就可以直接break掉,加快速度
            break;
        }
        if (P[i]&&huiwen(i)) {
                cout << i << endl;
            
        }
    }

}

        撒花!所有的知识点还是要及时复习与巩固,也要不断的思考算法的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钟一淼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值