筛质数(埃氏筛)

2023-10-31 20:18
文章标签 质数 埃氏

本文主要是介绍筛质数(埃氏筛),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接
题意:给定一个正整数n,请你求出1~n中质数的个数。
输入格式
共一行,包含整数n。
输出格式
共一行,包含一个整数,表示1~n中质数的个数。
数据范围
1≤n≤1e6
输入样例:
8
输出样例:
4
思路1 (朴素做法):把1~n中2的倍数,3的倍数, 4的倍数……都删除,那么剩下的数就都是质数了。
代码实现: O(n * logn)

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e6 + 5;
int n, x;
int primes[N], res;
bool st[N];void get_primes(int n)
{for(int i = 2; i <= n; i ++){if(!st[i]){res ++ ;}for(int j = i + i; j <= n; j += i)st[j] = 1;}
}int main()
{cin >> n;get_primes(n);cout << res << endl;return 0;
}

埃氏筛法:我们会发现4的倍数也是2的倍数,所有我们只需要把所有质数的倍数删除就好。
代码实现: O(n * loglogn)

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e6 + 5;
int n, x;
int primes[N], res;
bool st[N];void get_primes(int n)
{for(int i = 2; i <= n; i ++){if(!st[i]){res ++ ;for(int j = i + i; j <= n; j += i)st[j] = 1;}}
}int main()
{cin >> n;get_primes(n);cout << res << endl;return 0;
}

当然这还可以优化一下,变成一个基本上线性的算法。
代码实现: O(n)

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e6 + 5;
int n, x;
int primes[N], res;
bool st[N];void get_primes(int n)
{for(int i = 2; i <= n; i ++){if(!st[i]) primes[res ++ ] = i;//这里不用加j <= cnt的限制条件,因为当i是合数的时候,primes[j]遇到i的最小因子就会停下来,当i是质数的时候,primes[j] = n / i后也会停下来for(int j = 0; primes[j] <= n / i; j ++){st[primes[j] * i] = 1;//primes[j]一定是i的最小质因子if(i % primes[j] == 0) break;//一定会筛掉所有合数,例如4会把它的最小质因子2筛掉}}
}int main()
{cin >> n;get_primes(n);cout << res << endl;return 0;
}

这篇关于筛质数(埃氏筛)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/317854

相关文章

js算法题,给任意一个偶数,找出他的所有的质数因子

/*给任意一个偶数,找出他的所有的质数因子*/ function primeFactor(n){     var factors=[],            divistor=2;     if(typeof n !=='number'||!Number.isInteger(n)){          return 0;     }; //如果不是偶数返回0,如果是0,返回0

求素数的几个方法(最朴素版、n*sqrt(n)版、埃氏筛、欧拉筛)

最朴素版O(n^2) #include <bits/stdc++.h>using namespace std;int n, cnt, prim[6000000];bool flag; //true 表示质数int main(){scanf("%d", &n);for(int i=2; i<=n; ++i){flag=true; //默认为质数for(int j=2; j<=i-

Python 埃氏筛法

# -*- coding: utf-8 -*-# filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。# 构造一个奇数序列,排除了所有偶数,因为除了2之外的偶数都是非素数def _odd_iter():a = 1while True:a = a + 2yield a #

算法---计数质数(Java)

题目:计数质数 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。 示例 1: 输入:n = 10 输出:4 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 示例 2: 输入:n = 0 输出:0 示例 3: 输入:n = 1 输出:0 提示: 0 <= n <= 5 * 106 解决方法:(埃氏筛) 思路: 算法由希腊数学家厄拉多塞(\rm

leetcode 204:计数质数

int countPrimes(int n) {if(n<=0)return 0;int c=0;for(int i=2;i<n;i++){int flag=0;for(int j=2;j<=std::sqrt(i);j++){if(i%j==0){flag=1;break;}}if(flag==0)c++;}return c;}

第九届中国大学生程序设计竞赛(秦皇岛)-(CCPC2023-Qinhuangdao F - 质数之谜(DP)

题意 给定一个序列,修改最少数量的元素使得任意i属于[1,n-1],q[i]+q[i+1]都为质数,输出最小修改次数 思路 首先手玩的过程中可以发现,     如果因为前面一个数字和自己相加不是质数然后我把自己变成了奇数,那么如果我后面一个数字是偶数     可以发现自己肯定能找到另一个奇数使得和前面相加互质并且和后面相加也互质     举个例子:假设为2 8 10,我此时是8,我发现2+

力扣刷题--762. 二进制表示中质数个计算置位【简单】

题目描述🍗 给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。 计算置位位数 就是二进制表示中 1 的个数。 例如, 21 的二进制表示 10101 有 3 个计算置位。 示例 1: 输入:left = 6, right = 10 输出:4 解释: 6 -> 110 (2 个计算置位,2 是质数) 7

《算法竞赛进阶指南》0x31质数

定义 若一个正整数无法被除了1和它本身之外的任何自然数整除,则称这个数为质数(素数),反之为合数。 对于一个足够大的整数N,不超过N的质数大约有 N/lnN个,分布比较松散。 质数的判定 试除法 若一个正整数N为合数,则存在一个能整除N的数T,其中 2 ≤ T ≤ N 2\leq T \leq \sqrt{N} 2≤T≤N ​。 因此,我们只需要扫描 [ 2 , N ] [2,\sqr

筛质数zz

给定一个正整数 nn,请你求出 1∼n1∼n 中质数的个数。 输入格式 共一行,包含整数 nn。 输出格式 共一行,包含一个整数,表示 1∼n1∼n 中质数的个数。 数据范围 1≤n≤1061≤n≤106 输入样例: 8 输出样例: 4 #include <iostream>using namespace std;const int N=1e6+10;int cnt;

Python 判断质数

a = raw_input() #输入数字a = int(a) #强制转换成intb=True #一个标记for i in range(2,a): #从2开始循环本身if a%i==0: #如果除了本身和1以外还能被整除b=False #标记改成Falsebreak #循环结束if b:print 'YES'else:print 'NO'