01 质数筛

一、根据概念进行枚举

1、判断质数的枚举算法

根据概念:除了1和它本身以外没有其他约数的数为质数

//输入一个数n,判断n是不是质数
#include<bits/stdc++.h>
using namespace std;int main(){int n;cin>>n;//根据概念:除了1和它本身以外没有其他约数的数为质数bool flag=1;for(int i=2;i<n;i++)  if(n%i==0){flag=0;break;	} if(flag) cout<<"YES";else cout<<"NO";return 0;
}

2、枚举的范围进行优化

如果n有约数,则n的约数是成对存在的,一个小于\sqrt{n},另外一个则大于\sqrt{n},可以举例理解,对于一个1~\sqrt{n}的约数,则有一个\sqrt{n}~n的约数与之对应,所以判断n有没有约数只要判断前面1~\sqrt{n}的范围的即可,时间复杂度为O(\sqrt{n})

//输入一个数n,判断n是不是质数
#include<bits/stdc++.h>
using namespace std;int main(){int n;cin>>n;bool flag=1;for(int i=2;i*i<n;i++) //枚举方式进行优化 if(n%i==0){flag=0;break;	} if(flag) cout<<"YES";else cout<<"NO";return 0;
}

二、朴素筛法

思路分析:

从2到n进行遍历,对于遍历到的数如果没有被筛掉,就说明该数是素数。然后每次把遍历到的数i的倍数都筛去。为什么说这个方案可以筛出质数可行呢?因为对于一个数p,它如果没有被筛掉,就说明其不是前面2~p-1的倍数,也就是说2~p-1不存在p的约数,这不就是素数的定义!

代码实现:

//输入一个数n,输出1-n中质数的个数
#include<bits/stdc++.h>
using namespace std;
const int N=100010;bool st[N];
int prime[N],idx;
int main(){int n;cin>>n;for(int i=2;i<=n;i++){if(!st[i]) prime[++idx]=i;//用i筛掉后面i的倍数for(int j=i*2;j<=n;j+=i) st[j]=true;}cout<<idx<<endl;return 0;
}

时间复杂度分析 

对于数i来说:

i=2,筛掉n/2-1个数 (因为i是从2*i个数开始的,i不会被不能重复筛掉,所有要减一)

i=3,筛掉n/3-1个数

i=4,筛掉n/4-1个数

.......

i=n,筛掉n/n-1个数

循环次数为:

\frac{n}{2}-1+\frac{n}{3}-1+....\frac{n}{n}-1=n*(\frac{1}{2}+\frac{1}{3}+....\frac{1}{n})-(n-1)

对于\frac{1}{2}+\frac{1}{3}+....\frac{1}{n}是一个调和级数,其值等于\ln n+C,带入上述公式结果为:

n*(\ln n+C)-n+1=n*(\ln n+C-1)+1

去掉常数项,总的时间复杂度为O(n\ln n),等价于O(nlogn)

三、埃氏筛法

思路分析:

​ 根据通过质数去把所有合数都删掉的思路,可以优化方一的普通筛法。(因为合数都可以以质数的乘积形式获得)

代码实现:

//输入n,输出1~n中质数的个数
#include<bits/stdc++.h>
using namespace std;
const int N=100010;bool st[N];
int prime[N],idx;
int main(){int n;cin>>n;for(int i=2;i<n;i++){if(!st[i]) prime[++idx]=i;else continue;//用i筛掉后面i的倍数for(int j=i*2;j<=n;j+=i) st[j]=true;}cout<<idx<<endl;return 0;
}

时间复杂度分析:O(nloglogn)

四、线性筛法

思路分析:

线性筛法的核心思路就是每个数只会被其最小质因子筛掉,因为每个数只有一个最小质因子,所以每个数都只会被删一次,所以是线性的。

代码实现:

//输入n,输出1~n中质数的个数
#include<bits/stdc++.h>
using namespace std;
const int N=100010;bool st[N];
int prime[N],idx;
int main(){int n;cin>>n;for(int i=2;i<=n;i++){if(!st[i]) prime[++idx]=i;for(int j=1;prime[j]*i<=n;j++){st[i*prime[j]]=true;//如果prime[j]是i的一个质因子,那么i乘以任何一个数的乘积都包含质因子prime[j]//如果继续筛下去对于k=i*prime[j+1],prime[j+1]肯定大于prime[j],使用prime[j+1]筛选k//而不是使用prime[j]筛选k,与线性筛的要求不符if(i%prime[j]==0) break;}}cout<<idx<<endl;return 0;
}

时间复杂度分析:O(n)

因为每个合数的最小质因子只有一个,所以每个数只会被筛掉一次,所以时间复杂度为O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/434637.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主成分分析(PCA)Python

实际问题研究中&#xff0c;常常遇到多变量问题&#xff0c;变量越多&#xff0c;问题往往越复杂&#xff0c;且各个变量之间往往有联系。于是&#xff0c;我们想到能不能用较少的新变量代替原本较多的旧变量&#xff0c;且使这些较少的新变量尽可能多地保留原来变量所反映的信…

代码随想录刷题笔记-Day12

1. 二叉树的递归遍历 144. 二叉树的前序遍历https://leetcode.cn/problems/binary-tree-preorder-traversal/94. 二叉树的中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/145. 二叉树的后续遍历https://leetcode.cn/problems/binary-tree-postorder-tra…

第8章 异常

第8章 异常 学习目标 能够辨别程序中异常和错误 说出异常的分类 说出虚拟机处理异常的方式 列出常见的5个运行时异常 列出常见的5个编译时异常 能够使用try…catch关键字处理异常 能够使用throw抛出异常对象 能够使用throws关键字处理异常 能够自定义异常类 能够处理自定义异常…

小迪安全21WEB 攻防-JavaWeb 项目JWT 身份攻击组件安全访问控制

#知识点&#xff1a; 1、JavaWeb 常见安全及代码逻辑 2、目录遍历&身份验证&逻辑&JWT 3、访问控制&安全组件&越权&三方组件 Java&#xff1a;大部分都是第三方插件出现漏洞 webgoat的搭建&#xff1a;——java靶场 JDK版本要求&#xff1a;11.0…

[01 LinuxShell ] 清华大学电子系科协软件部2023暑期培训

清华大学电子系科协软件部2023暑期培训_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV11N4y187ZE/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&vd_source3ef6540f8473c7367625a53b7b77fd66 本视频为清华大学电子系科协软件部2023…

领域驱动设计(Domain-Driven Design DDD)——通过重构找到深层次模型1

一、概述 重构就是在不改变软件功能的前提下重新设计它。开发人员无需在着手开发之前做出详细的设计决策&#xff0c;只需要在开发过程中不断小幅调整设计即可&#xff0c;这不但能够保证软件原有的功能不变&#xff0c;还可使整个设计更加灵活易懂。 我们面临的真正挑战是找到…

Vue3中的ref和shallowRef、reactive和shallowReactive

一&#xff1a;ref、reactive简介 ref和reactive是Vue3中定义响应式数据的一种方式。ref通常用来定义基础类型数据。reactive通常用来定义复杂类型数据。 二、shallowRef、shallowReactive简介 shallowRef和shallowReactive是Vue3中定义浅层次响应式数据的方式 三、Api使用对比…

套接字的多种可选项(修改IO缓冲区大小及TCP_NODELAY)

标题套接字的多种可选项 我们进行套接字编程时往往只关注数据通信&#xff0c;而忽略了套接字具有的不同特性。但是&#xff0c;理解这些特性并根据实际需要进行更改也十分重要。 从上表可以看出&#xff0c;套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项&#x…

【JavaSE篇】——数组的定义与使用

目录 本章的目标&#xff1a; &#x1f388;数组的基本概念 &#x1f36d;创建数组 &#x1f36d;数组的初始化 &#x1f36d;数组的使用 &#x1f449;数组中元素访问 &#x1f449;遍历数组 &#x1f388;数组是引用类型 &#x1f36d;初始JVM的内存分布 &#x1f…

2024017期传足14场胜负前瞻

2024017期赛事由亚洲杯2场、英总杯2场、德甲2场、意甲4场、西甲4场组成。售止时间为1月28日&#xff08;周日&#xff09;19点00分&#xff0c;敬请留意&#xff1a; 本期深盘场次同样适中&#xff0c;1.5以下赔率3场&#xff0c;1.5-2.0赔率6场&#xff0c;其他场次基本皆是平…

Java复习系列之阶段二:数据库

1. 基础语法 1.1 DQL&#xff08;数据查询语句&#xff09; 执行顺序&#xff1a; from、join 、on、where、group by、having、select、distinct、order by、limit 1.2 DML&#xff08;数据修改语言&#xff09; 对数据表的增删改 insert into update set delete form 1.…

javax.servlet.http包

javax.servlet.http包 javax.srvlet.http包是对javax.servlet包的扩展。该包的类和接口处理使用HTTP进行通信的servlet。这些servlet也称为HTTP Servlet。您需要扩展HttpServlet类来开发HTTP Servlet。javax.servlet.http包经常使用的接口包括: HttpServletRequest接口HttpSe…