第1关:欧拉筛法求素数

时间: 2025-06-20 21:36:24 AIGC 浏览: 32
### 欧拉筛法求素数的算法实现 欧拉筛法是一种高效的素数筛选方法,能够在 \(O(n)\) 的时间复杂度下找到指定范围内所有的素数。其核心思想是通过已知的素数逐步排除掉那些可以由较小素数乘积构成的合数。 以下是基于 C++ 实现的一个完整的欧拉筛法代码示例: ```cpp #include <iostream> #include <vector> using namespace std; const int MAXN = 1000000; // 定义最大范围 int prime[MAXN], is_prime[MAXN], cnt = 0; // prime用于存储素数,is_prime用于标记素数(0为素数,1为合数),cnt记录素数个数 void euler_sieve(int n) { for (int i = 2; i <= n; i++) { if (!is_prime[i]) { // 如果当前数未被标记为合数,则它是素数 prime[cnt++] = i; // 将该素数存入prime数组 } for (int j = 0; j < cnt && i * prime[j] <= n; j++) { is_prime[i * prime[j]] = 1; // 标记i*prime[j]为合数 if (i % prime[j] == 0) break; // 当前i能够被prime[j]整除时退出循环 } } } int main() { int n; cout << "请输入一个正整数N:" << endl; cin >> n; euler_sieve(n); cout << "N内的所有素数及个数如下:" << endl; for (int i = 0; i < cnt; i++) { cout << prime[i] << endl; } cout << "共有" << cnt << "个素数" << endl; return 0; } ``` #### 关键点解析 1. **初始化** 使用 `is_prime` 数组来标记某个数字是否为素数,初始状态下假设所有大于等于2的数字均为素数[^2]。 2. **外层循环** 遍历从2到n的所有数字,如果某数字未被标记为合数,则将其视为素数并保存至 `prime` 数组中[^2]。 3. **内层循环** 对于每一个新发现的素数,利用它去标记它的倍数为合数。为了避免重复标记某些数字,当满足条件 `i % prime[j] == 0` 时立即跳出循环[^2]。 4. **效率优化** 每个合数只会被其最小质因数对应的素数标记一次,因此整个过程的时间复杂度降低到了线性级别 $ O(n) $。 --- ###
阅读全文

相关推荐

第1关:素数判断 200 学习内容 参考答案 记录 评论67 任务描述 相关知识 如何判断一个正整数是否是素数 编程要求 测试说明 任务描述 本关任务:编写一个能判断一个整数是否是素数的小程序。 相关知识 为了完成本关任务,你需要掌握: 如何判断一个正整数是否是素数。 如何判断一个正整数是否是素数 素数(Prime Number),又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数;否则,称为合数(Composite Number)。1既不是素数,也不是合数。 如2、3、5、7、11都是素数,因为找不到除了1和其本身之外的约数;而4、6、8都是合数,因为4可以整除2,6可以整除2和3,8可以整除2和4。 而一个数的约数必然是不超过该数的,加上素数必需是只有1和本身是其约数的条件。于是,我们可以通过枚举小于该数,并且大于1的整数,来判断该数是否是素数。 假设有一个正整数a,则其可以被写成任意两个正整数之积,即a = p * q。假设p < q,那么正整数p和q都是a的约数。注意到,如果我们知道p是a的约数,那么可以通过q = a / p快速求得另外一个约数q。同样的道理,如果某个数p不是a的约数,那么q也不是a的约数。这就意味着我们在枚举约数的时候,只需要枚举2到不大于sqrt(a)的正整数即可。 虽然通过上述方法,已经能让我们在根号级别的复杂度内,判断一个正整数是否为素数。但是我们其实还可以做得更快!回到我们最初的起点,我们之所以要枚举这些数,就是想找出原数的约数。然后除1外,任何一个正整数都能写成多个素数的乘积的形式,所以我们枚举特定范围内的所有素数,也能达到相同的效果,而且数字范围越大,其区间内素数个数和区间长度之比也将越来越小,大家可以看看下面不同区间内的素数统计结果: 从上图的统计结果我们可以发现,我们用区间内的素数去判断一个整数是否素数,比较的次数相较之前来说更少。虽然就单次判断一个素数来说,这样的算法可能并没有优势,因为还需要时间去求出该区间内的所有素数。但是如果需要判断的数字很多,那么先把该区间内的所有素数求出来,无疑是个更好的选择。 而求不超过某个正整数x内的所有素数,有一个著名的算法——埃拉托斯特尼筛法。其算法描述为: 先用一个数组vis,把不大于该正整数x的所有正整数标记为0,表示没有访问; 然后从第一个素数2开始遍历整个区间,如果当前访问的数没有访问过,则可以认为它是一个素数。那么就将它在该区间内所有的倍数,全部标记为已访问,这样就保证外部的循环发现的没有访问过的数都是素数。 其具体实现如下述代码所示: def sieve(x): vis = [0 for i in range(x+1)] prime_table = [] for i in range(2, x+1): if vis[i] == 0: prime_table.append(i) for j in range(i*2, x+1, i): vis[j] = 1 return prime_table 然而,除了上述筛法,还有其他高效的筛法,比如欧拉筛法,这里只给出其代码实现,希望大家能仔细去体会。 def ouler(x): vis = [0 for i in range(x+1)] prime_table = [] ln = 0 for num in range(2, x+1): if vis[num] == 0: prime_table.append(num) ln += 1 for j in range(ln): if num * prime_table[j] > x: break vis[num * prime_table[j]] = 1 if num % prime_table[j] == 0: break return prime_table 编程要求 根据提示,在右侧编辑器Begin-End区间补充代码,实现判断一个正整数是否是素数。如果是,则返回True,否则返回False(注意,返回值是布尔值)。 提示:如

zip
标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。