C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法

这篇具有很好参考价值的文章主要介绍了C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

质数想必大家都不陌生

从小学到大

质数的概念:一个数如果除了1和本身之外没有其他的因子,那么这个数被称为质数

今天要讲两个知识点:

  1. 在C++中如何判断一个数是否为质数

  1. 在C++中如何判断1-N之间哪些数为整数

  1. 在C++中如何判断一个数是否为质数

这个知识点较为简单

充分利用上面的概念

我们用一个for循环来解决

因为对于每个数来说,1和n都是他们的因子

所以循环开始为2,终止为n-1

for (int i=2;i<n;i++){
    if (n%i==0){
        return false;
    }
}
return true;
But……

时间复杂度也忒高了吧

大概就是O(n)

那如果n>10^9的话,那直接出1秒了

所以还得优化

咱们来举个例子,n=16:

n的因子有

1 2 4 8 16

可以看出,4就像一条分割线,分成了前后两部分

前后一一对应

没错 优化的点找到了

循环前面的部分,如果前面都没有的话,那么后面肯定也没有

那么循环终止条件是什么呢?

4是16的什么数?

因数?

算术平方根!

也就是C++中的sqrt

恭喜你!优化成功

代码就不写了,就是把循环条件的n改成sqrt(n),然后加个cmath头文件

成功把时间复杂度降到O(C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法)

第一个问题成功解决

  1. 在C++中如何判断1-N之间哪些数为整数

会不会有一些小伙伴说了

哎哟不就是刚才的刚才的函数调用n编吗?至于单列出来一个标题吗~

NONONONONOONONNOONONONONONO

大错特错

这篇文章的主要就在这里

举个例子,10^9都用不上,咱就说n小于等于10^6,还是很常见的吧

那么时间复杂度就是O(10^6*循环次数)

也就那么亿点点的时间就好了

C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法

所以还是那句话,优化优化优化

恭迎今天主角:埃氏筛法!

网友:埃氏筛法 满足你的一切需要!

先讲一下他的思想

思想:
  1. 一个合数,一定可以拆成一个质数与另一个数的乘积

  1. 每个质数的倍数都是合数

基于以上这两条思想,就可以实现埃氏筛法

  1. 用一个数组表示每个数的状态,即是否为质数

  1. 循环每个数,如果是质数,就把他所有的倍数全部标为合数

没错就是这么简单

时间复杂度计算方面,我真的很拉

埃氏筛法大概O(n log n)左右吧

(大佬勿喷)

void eratosthemes_prim(int n){
    for (int i=2;i<=n;i++){
        if_p[i]=true;
    }
    for (int i=2;i<=n;i++){
        if (is_p[i]){
            num++;
            p[num]=i;//p数组存放质数,num代表目前质数个数
            for (int j=i<<1;j<=n;j+=i){
                is_p[j]=false;
            }
        }
    }
}

这样是不是快了很多?

别走!来看道简简单单的例题

Goldbach's Conjecture
题目描述

全屏
哥德巴赫猜想:任何大于4的偶数都可以拆成两个奇素数之和。 比如:

8=3+5

20=3+17=7+13

42=5+37=11+31=13+29=19+23

你的任务是:验证小于106的数满足哥德巴赫猜想。

输入
多组数据,每组数据一个n。

读入以0结束。

输出
对于每组数据,输出形如n = a + b,其中a,b是奇素数,=和+两边都有空格。若有多组满足条件的a,b,输出b-a最大的一组。
若无解,输出Goldbach's conjecture is wrong.。

样例输入1
8
20
42
0

样例输出1
8 = 3 + 5
20 = 3 + 17
42 = 5 + 37

提示/说明
【数据范围与提示】

对于全部数据,6≤n≤106。

思想:运用埃氏筛法筛出所有数的情况

循环遍历情况即可

# include <iostream>
# include <cstdio>
# include <cstring>
#define N 1000005
using namespace std;
int n,vis[N],flag;
int main(){
    memset(vis,0,sizeof(vis));
    vis[0]=vis[1]=1;
    for(int i=2;i<=N/2;i++){
        if(vis[i]==0){
            for(int j=2*i;j<=N;j=j+i){
                vis[j]=1;
            }
        }    
    }
    while(scanf("%d",&n)&&n){
        flag=0;
        for(int i=3;i<=N/2;i++){
            if(vis[i]==0&&vis[n-i]==0){
                printf("%d = %d + %d\n",n,i,n-i);
                flag=1;
                break;
            }
        }    
        if(flag==0){
            printf("Goldbach's conjecture is wrong.\n");
        }
    }
    return 0;
}

有些人也许会问

题目里说的是奇素数,可你的代码中没体现出奇数这个条件啊?

问这个问题的,思考一下,偶数可能是素数吗?所以不需要考虑

还有一个问题:陈景润都没证明出哥德巴赫是错的,你还判断一下有必要吗?

这个是可以删除的!

都看到这里了,不点个赞吗?

今天的质数就讲解到这里

欢迎大家关注我

持续更新——文章来源地址https://www.toymoban.com/news/detail-404168.html

到了这里,关于C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [超详细]3种方法判断一个数是否为质数(Python)

    (发现好多博客对第三种进阶方法说的不明白,至少我是没完全看明白。后面结合自己的理解应该算是弄懂了,供大家参考,欢迎纠正。) 方法一:最暴力,最简单,也最耗时O(n) 思想:由 素数的定义:一个数t,除了1和它本身,若没有其他因数,那么就称其为素数。 因此循环

    2024年04月08日
    浏览(48)
  • 埃氏筛与欧拉筛(线性筛)

    目录 一、前言 二、埃氏筛与欧拉筛(线性筛) 1、问题描述 2、基本思路 (1)埃氏筛法 (2)欧拉筛法 三、题例 1、上链接 2、简单思路 3、代码 (1)埃氏筛python版 (2)欧拉筛python版 对于学计算机的同学来说,学习算法是一件非常重要的事情,废话不多讲,我们来讲讲“埃

    2024年02月04日
    浏览(34)
  • C语言判断一个数是否是质数的几种常用方法(求100-1000以内的所有质数)

    要用代码判断一个数是否是质数,首先我们需要知道什么什么数称之为质数。质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。 以下有三种方法判定质数: 通过从2到n-1每个数均整除

    2024年02月08日
    浏览(94)
  • 一些些筛子(埃氏筛、线性筛、杜教筛)

    有时我们需要求出一个范围内的质数,或者要计算一些积性函数的值,但往往题目无法承受直接判断质数、直接求函数值的时间复杂度,这时我们就可以用筛子了 假设当前有一块板,板上写着 (2sim n) 的数,如果我们想快速找出质数,那么我们可以考虑标记那些合数,让划

    2024年02月05日
    浏览(30)
  • 204. 计数质数 (埃式筛法详解)——【Leetcode每日一题】

    素数最朴素判断思路:(一般会超时) 对正整数 n ,如果用 2 到 n sqrt{n} n ​ 之间的所有整数去除,均无法整除,则 n 为素数又称为质数。 为什么到 n sqrt{n} n ​ 就可以了,因为因数如果存在一定是成对出现的,如果存在小于根号n的因数,那么n除以它一定大于根号n。 首先

    2023年04月08日
    浏览(34)
  • [数论第一节]质数/约数

    质数 在大于1的整数中,只包含1和本身这两个约数,就被称为质数,也叫素数 质数的判定 试除法 遍历2-n,若有约数则不为质数 O(n) 优化: d整除n,则n/d也整除n,约数总是成对出现,只要找较小的约数,即取d = n/d,则d = sqrt(n) 只用遍历2-sqrt(n) O(sqrt(n)) 不用 i * i = n ,i过大会

    2024年02月14日
    浏览(41)
  • 关于质数筛——数论

    埃式筛法  欧拉筛

    2024年02月15日
    浏览(34)
  • C++判断一个数是否为回文数的算法

    C++判断一个数是否为回文数的算法 回文数是指正序(从左向右)和倒序(从右向左)读都相同的整数。在C++中,我们可以使用算法来判断一个数是否为回文数。下面是一个详细的解释和相应的源代码。 算法思路: 将给定的整数转换成字符串。 使用双指针法来检查字符串的左

    2024年02月06日
    浏览(53)
  • C语言判断素数的三种方法 判断素数(质数)

    题目: 方法一:在2到n-1之间任取一个数,如果n能被整除则不是素数,否则就是素数 代码示例如下: 代码运行结果如下: 方法二:在2到n/2之间任取一个数,如果n能被整除则不是素数,否则就是素数  代码示例如下: 代码运行结果如下: 方法三:在2到sqrt(n)之间任取一个数,如

    2024年02月02日
    浏览(103)
  • C 练习实例33 - 质数(素数)判断

    题目: 判断一个数字是否为质数。 程序分析: 质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除。 这题做过很多遍了,懂得都懂。 代码:

    2024年01月21日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包