背景:

素数(即质数)问题是老问题了,程序员面试问题,大小比赛的热门题。

比如 最简单的判断素数问题,或者计算素数的个数,等等。

简单的判断素数函数:

素数的定义:指在大于1的整数中,只能被1和它本身整除的数。

1既不是素数也不是合数

2是最小的素数

试除法原理:非素数k必定可以被一个小于等于√k的素数整除。

int prime(int n)
{if(n==1)return 0;if(n==2)return 1;//函数调用 还有 循环的时间 对付一些入门简单题的//时间复杂度为√nfor(ll i=2;i*i<=n;i++){if(n%i==0)//如果有 能被n除的数 ,即n的因子不只是1和本身,不符合素数的概念//返回0return 0;}return 1;
}

埃氏筛法求素数:

题目:从2到N,每个数判断是否有1和它本身以外的其他因数。

首先将0、1排除:

对于初始队列{2,3,4,5,6,7,8,9,10,11,12,13,14……n},操作步骤如下:

(1)输出最小的素数2,然后筛选掉2的倍数,剩下{3,5,7,9,11,13,……}

(2)输出最小的素数3,然后筛选掉3的倍数,剩下{5,7,11,13,……}

(3)输出最小的素数5,然后筛选掉5的倍数,剩下{7,11,13,……}

继续上面步骤,直到队列为空。

初始化 p = 2,因为2是最小的质数;

枚举所有p的倍数(2p,3p,4p,…),标记为非质数(合数)

找到下一个 没有标记 且 大于p 的数。如果没有,结束运算;如果有,将该值赋予p,重复步骤;

运算结束后,剩下所有未标记的数都是找到的质数。

上动图理解一下:

下面是程序,visit[i]记录i的状态,如果visit[i]=true,表示它被筛选掉了(不是素数)。用prime[]存放素数,例如prime[0]是第一个素数2。

const int maxn=1e7;//定义空间大小,约为10MB
int prime[maxn+1];//存放素数,记录visit[i]=false的项
bool visit[maxn+1];//true表示被筛掉(非素数)
int E_sieve(int n)//埃氏筛法,计算[2,n]内的素数
{int k=0;//统计素数的个数 for(int i=0;i<=n;i++)visit[i]=false;//初始化for(int i=2;i<=n;i++){if(!visit[i]){prime[k++]=i;//i是素数,存入prime[]中 for(int j=2*i;j<=n;j+=i)//i的倍数都不是素数 {visit[j]=true;//标记为true筛掉 }} } return k;
}

这个算法的核心思想是:任何一个p值都是质数,如果存在一个合数,那么就应该存在一个质数能够标记它。

算法的时间复杂度为:O(n/2+n/3+n/5+……)=O(n log log2 n)。

算法的空间复杂度为:当maxn=1e7时约为10MB。一般题目会限制空间为65MB,所以n不能再大了。

当然代码还有两处可以优化。

(1)用来做筛选的数为2,3,5……,最多到√n就可以了。

例如求n=100以内的素数,用2,3,5,7筛选足够了。原理和试除法类似。

(2)for(int j=i*2;j<=n;j+=i)中的j=i*2可以优化为j=i*i。例如i=5时,2*5、3*5、4*5已经在前面i=2,3,4筛选过了。

优化后的代码为:

const int maxn=1e7;//定义空间大小,约为10MB
int prime[maxn+1];//存放素数,记录visit[i]=false的项
bool visit[maxn+1];//true表示被筛掉(非素数)
int E_sieve(int n)//埃氏筛法,计算[2,n]内的素数
{for(int i=0;i<=n;i++)visit[i]=false;//初始化for(int i=2;i*i<=n;i++)//筛选掉非素数 {if(!visit[i]){for(int j=i*i;j<=n;j+=i)//i的倍数都不是素数 {visit[j]=true;//标记为true筛掉 }} } int k=0;//统计素数的个数 for(int i=2;i<=n;i++){if(!visit[i]){prime[k++]=i;//i是素数,存入prime[]中 } } return k;
}

看到这里写一题练练手吧:http://onlinejudege.me/problem/1195​​​​​​

可能会卡的进不去,学校的OJ不太行。题面在这里:

超时我已经麻了。。。。

AC代码:

#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=5000000;//定义空间大小,约为10MB
int mn[maxn+1];//存放素数,记录visit[i]=false的项
bool visit[maxn+1];//true表示被筛掉(非素数)
int flag=0;
int fun()
{int k=0;//统计素数的个数for(int i=0;i<maxn;i++)visit[i]=false;//初始化visit[0]=true;        visit[1]=true;for(int i=2;i*i<=maxn;i++)//筛选掉非素数{if(!visit[i]){for(int j=i*i;j<=maxn;j+=i)//i的倍数都不是素数{visit[j]=true;//标记为true筛掉}}}for(int i=0;i<maxn;i++){if(!visit[i])mn[flag++]=i;}return flag;
}int fun1(int *arr , int low , int high , int target)//递归实现二分
{int middle = (low + high)/2;if(low > high)return -1;if(arr[middle] <=target&&arr[middle+1] >target)return middle;if(arr[middle] > target)return fun1( arr , low , middle - 1 , target);if(arr[middle] < target)return fun1( arr , middle + 1 , high , target);
}int main()
{std::ios::sync_with_stdio(false);int n,a,m,flag,flag1,flag2;flag1=fun();scanf("%d",&n);while(n--){scanf("%d%d",&a,&m);flag2=fun1(mn,0,flag1,a);printf("%d\n",mn[flag2+m]);}return 0;
}

拿去吧,拿去给皇上看,你跟他说,这都是本宫自己抄的,没有假手于人,本宫的手都要断了。

------------哈哈哈哈哈哈

埃拉托色尼筛选法巧解质数问题(埃氏筛法求解素数问题)相关推荐

  1. python筛选法求素数讲解_埃氏筛选法求素数 Python

    代码如下 def _odd_iter(): # 构建奇数序列 从3开始 n = 1 while True: n = n + 2 yield n def _not_divisible(n): retur ...

  2. 进阶必备:素数筛法(欧拉,埃氏筛法)

    筛选素数其实有两种比较高效的算法可以提供选用,分别是:Eratosthenes筛选法与欧拉筛选法.但是欧拉算法的普适性比较高,所以这里就只介绍欧拉函数的算法. 筛选的范围较小的话,欧拉算法,数据较大, ...

  3. 埃拉托色尼筛选法------筛选质数

    前戏:本篇介绍一种特定数据范围内统计该段数据内所有质数的高效算法,埃拉托色尼筛选法. 正文: 1.埃拉托色尼筛选法: 埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法 ...

  4. 素数处理-埃拉托色尼筛选法(埃式筛)

    素数处理-埃拉托色尼筛选法(埃式筛) 埃拉托色尼筛选法(The Sieve of Eratosthenes) 继欧拉筛之后,我今天补的一篇博客.名字太长了emm.简称就是埃式筛法. 埃筛只能解决1e7 ...

  5. Day5:计数质数(埃拉托色尼筛选法)

    leetcode地址:https://leetcode-cn.com/problems/count-primes/ Day5:计数质数 一. 问题背景: 统计所有小于非负整数 n 的质数的数量. 二. ...

  6. c语言埃拉托色尼筛选法数组,埃拉托色尼筛选法 算法

    埃拉托色尼筛选法 埃拉托色尼选筛法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosthenes 274B.C.-194B.C.)提出的一种筛选 ...

  7. Java 埃拉托色尼筛选法

    埃拉托色尼筛选法 埃拉托色尼筛选法 概念 步骤 优化 代码 埃拉托色尼筛选法 概念 埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼提出的一 ...

  8. Java实现埃拉托色尼筛选法

    1 问题描述 Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes. 翻译:使用埃拉托色尼筛选 ...

  9. 埃拉托色尼筛选法 C++实现

    在公元前3世纪,古希腊天文学家埃拉托色尼发现了一种找出不大于n的所有自然数中的素数的算法,即埃拉托色尼筛选法. 具体筛选步骤: 这种算法首先需要按顺序写出2到n中所有的数. 然后把第一个元素画圈,表示 ...

最新文章

  1. Redis为什么这么快?一文深入了解Redis内存模型!
  2. 蚂蚁森林合种计划(2020.12.12,7天有效,每周6更新)
  3. html进度条圆圈渐变色,HTML5 canvas带渐变色的圆形进度条动画
  4. 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)
  5. 专访:Vmware眼中的虚拟化
  6. Cpp 对象模型探索 / 对象访问成员变量的原理
  7. 已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和集合B的差集(近由在A中出现而不再B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
  8. JSONObject,JSONArray,对象,数组互相转化
  9. 不同语言Sql Server的库交换出现乱码
  10. 常用类字符串详解大全String
  11. 3. DICOM图像层级分类-DCMTK-数据字典避坑
  12. cad命令栏怎么调出来_Solidworks工具栏,功能区不见了,怎么调出来?
  13. linux软件安装文档总结
  14. 分析入门股票量化交易券商接口的方法
  15. 最强大脑记忆曲线(1)
  16. MFC图形界面编辑工具
  17. 苹果vs剪辑下载_好用的短视频制作与剪辑APP工具盘点
  18. 项目无法识别 ?. 语法,导致报错Module parse failed: Unexpected token
  19. 数字信号处理之期中斩神篇(一重 搬山)
  20. 实例检索︱图像的实例搜索(文献、方法描述、商业案例)

热门文章

  1. 华为路由器学习指南_BGP_路由反射器与联盟
  2. 电脑的ppt打不开计算机二级,打不开电脑中的ppt文件并提示访问出错的解决方法...
  3. 逼自己一把,你就优秀了 【转】
  4. 3599元起 铭凡推出NPB7迷你主机:i7-13700H、双雷电4
  5. echart自定义图例icon的形状
  6. Logcat五种级别日志
  7. 日记侠:你想开始写文章吗?(可以赚钱的)
  8. 终止正在运行的ORACLE作业
  9. 区块链黑暗森林自救手册
  10. HDU 5547 数独(DFS变形+4*4数独)