算法刷题-数论-质数的判定、分解质因数、筛质数
文章目录
- 数论
- 1. 质数
- 质数的判定---试除法
- 分解质因数---试除法
- 筛质数
- 朴素筛法
- 埃氏筛法
- 线性筛法
数论
1. 质数
质数:在大于1的整数中,如果只包含1和它本身这两个约数,那么这个数就称为质数。
判断质数最暴力的写法,按照质数的定义:看是否有其他的因子。
最朴素的暴力的时间复杂度O(n)
//时间复杂度O(n)
bool isPrime(int n){if(n<2) return false;for(int i=2;i<n;i++)if(n%i==0) return false;return true;}
质数的判定—试除法
题目链接:Acwing866. 试除法判定质数
优化:枚举到n\sqrt{n}n,因为因数都是成对出现的,
如果d是n的因子,那么n/d也是n的因子,所以只需要枚举一部分就行,枚举哪一部分呢?就是d≤n/d 推出,d≤nd≤\sqrt{n}d≤n
这里n\sqrt{n}n的写法需要注意,这种调用数学函数n\sqrt{n}n的写法不好,太慢;另外写成i∗i≤ni*i≤ni∗i≤n存在溢出风险,最好的写法是i≤n/ii≤n/ii≤n/i
试除法求质数的时间复杂度O(n\sqrt{n}n)
//优化成O(根号n)
bool isPrime(int n){if(n<2) return false;for(int i=2;i<=n/i;i++)if(n%i==0) return false;return true;}
分解质因数—试除法
题目链接:Acwing867. 分解质因数
暴力求质因数
下面i就是质因子,s是质因子i的阶数。
暴力的时间复杂度O(n)
void divide(int n){for(int i=2;i<=n;i++){if(n%i==0){ //i一定是质数,因为下面n/=i,n一直在更新,如果是合数的话,已经被2除干净了int s=0;//统计质因子的阶数while(n%i==0){s++;n/=i;}cout<<i<<" "<<s<<endl;}}
}
优化
给出一个重要性质:正整数n的因子中,最多包含1个大于n\sqrt{n}n的质因子。(可以用反证法来证明)
这里试除法的优化就是枚举到n\sqrt{n}n,然后剩下的1个大于n\sqrt{n}n的质因子单独处理,这样试除法分解质因数的时间复杂度O(n\sqrt{n}n)
ac代码
#include<bits/stdc++.h>
using namespace std;//试除法分解质因数
void divide(int n){//处理≤sqrt(n)的质因子for(int i=2;i<=n/i;i++){if(n%i==0){int s=0;while(n%i==0){s++;n/=i;}cout<<i<<" "<<s<<endl;}}//单独处理大于sqrt(n)的质因子if(n>1) cout<<n<<" "<<1<<endl;}int main(){int n;cin>>n;int tmp;for(int i=0;i<n;i++){cin>>tmp;divide(tmp);cout<<endl;}}
筛质数
题目链接acwing868. 筛质数
朴素筛法
朴素筛法的思想:从小到大枚举所有数,每次删掉该数的所有倍数,比如枚举到2,就删掉所有2的倍数。枚举到3,就删掉所有3的倍数。
需要用到prime数组,用来存放所有的质数;st数组,用来记录是否是某个数的倍数,即判断哪些是质数。需要count1变量,来存储质数的个数。
遍历的时候,需要考虑等号取不取。
朴素筛法的时间复杂度O(n×logn)O(n\times logn)O(n×logn)
#include<bits/stdc++.h>
using namespace std;const int maxn=1000010;int prime[maxn];//prime数组存的是从小到大的质数
int count1=0; //质数的个数
bool st[maxn]; //判断是否是质数//朴素的筛法
void primeNumber(int n){for(int i=2;i<=n;i++){if(!st[i]){ //i不是别人的倍数,那么就是质数prime[count1++]=i;}for(int j=i+i;j<=n;j+=i) st[j]=true;//倍数筛掉}cout<<count1<<endl;}int main(){int n;cin>>n;primeNumber(n);return 0;}
埃氏筛法
优化:不需要筛掉所有数的倍数(合数的倍数一定不是质数,不用管),只需要筛掉质数的倍数,(因为质数的倍数是合数)。
//优化的筛法
void primeNumber1(int n){for(int i=2;i<=n;i++){if(!st[i]){ //i不是别人的倍数,那么就是质数prime[count1++]=i;for(int j=i+i;j<=n;j+=i) st[j]=true;//质数的倍数筛掉} }cout<<count1<<endl;}
有质数定理:当n很大时,1~n中有nlnn\frac{n}{lnn}lnnn个质数。
优化的筛法(埃氏筛法)时间复杂度O(n×loglogn)O(n\times loglogn)O(n×loglogn),可以粗略地看成是O(n)。
两次提交结果
线性筛法
先说效率,数量级在10^7时候,线性筛法比埃氏筛法快一倍大概。
线性筛法时间复杂度O(n)
线性筛法的核心:一个数k只会被k的最小质因子筛掉。
//线性筛法void primeNumber2(int n){for(int i=2;i<=n;i++){if(!st[i]) prime[count1++]=i;for(int j=0;prime[j]<=n/i;j++){st[prime[j]*i]=true;if(i % prime[j]==0) break; //prime[j]一定是i的最小质因子}}cout<<count1<<endl;
}
补充
如何找到第一个大于100000的质数呢?
解答:就是使用试除法判断质数的方法,从100000开始遍历,使用标志flag,如果i不是质数,flag=false;如果i是质数,flag=true;然后判断flag如果等于true,就break跳出循环,输出i,即为大于100000的最小质数。
#include<bits/stdc++.h>
using namespace std;const int maxn=100000;int main(){for(int i=maxn;;i++){bool flag=true;for(int j=2;j<=i/j;j++){if(i%j==0){flag=false;break;}}if(flag){cout<<i<<endl;break;}}}
算法刷题-数论-质数的判定、分解质因数、筛质数相关推荐
- 算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)
文章目录 acwing869. 试除法求约数 acwing870. 约数个数 acwing871. 约数之和 acwing872. 最大公约数 acwing869. 试除法求约数 acwing869. ...
- 算法刷题-数论-组合数、快速幂、逆元、递推求组合数、逆元求组合数
文章目录 acwing885. 求组合数 I(递推:数据范围:2000) acwing875. 快速幂(a的k次方 模 b) acwing876. 快速幂求逆元 acwing886. 求组合数 II( ...
- 找到所有数组中消失的数字_【一点资讯】千万程序员的呼声:面试如何拿到大厂Offer?这份阅读量超过11W+的算法刷题宝典请你原地查收 www.yidianzixun.com...
如何才能通过面试拿到大厂Offer? "刷leetcode!" 这是我听到最多的回答! 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是面测试.算 ...
- 神了,无意中发现一位1500道的2021LeetCode算法刷题pdf笔记
昨晚逛GitHub,无意中看到一位大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到. 关于算法刷题的困惑和疑问也经常听朋友们提及.这份笔记 ...
- 【c++算法刷题笔记】——洛谷2
1. 洛谷练习--P1579 哥德巴赫猜想(升级版) 题目描述: 现在请你编一个程序验证哥德巴赫猜想. 先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数. 输入格式: 仅有一行,包含一 ...
- 搬砖试金石!github星标7W算法刷题宝典,还愁拿不下大厂offer?
前言 这几年IT技术蓬勃发展,日新月异,对技术人才的需求日益增长,程序员招聘市场也如火如荼.在有限的三五轮面试中,国外流行让面试者编程解决某些数据结构和算法的题目,通过观察面试者编码的熟练程度.思考的 ...
- 一夜登顶GitHub!字节内网数据结构与算法刷题笔记,看完直呼卧槽
网络上流传着一句段子"程序员两条腿,一条是算法,一条是英文,想跑的更远,这两条腿都不能弱".英文,我们暂且不谈,我们先来谈谈算法. 算法之难,在于将精巧的逻辑,通过合适的数据结构, ...
- 字节跳动算法刷题宝典.pdf
今天推荐一个关于「算法刷题宝典」的开源项目:力扣Cookbook. 力扣 Cookbook是@halfrost(中文名:霜神)去年刷的 力扣整理出的 520 题,每道题都写了解题思路,并且每题都 ru ...
- Github最强算法刷题笔记.pdf
资料一 昨晚逛GitHub,无意中看到一位大佬(https://github.com/halfrost)的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙 ...
最新文章
- 在 AI Studio中利用Paddle实现经典的AlexNet
- webbrowser selstart selLength
- SSM整合shiro权限框架
- 全球及中国USB分路器行业发展布局与应用现状调研报告2022年
- 网易云信阮良: 让客户能够连接一切,把整个精彩的世界连接起来
- c语言程序设计第二版李学刚,C语言程序设计(第2版)李学刚教学资源教学课件2-7 动态变量.pptx...
- U-Boot-2009-03移植笔记(移植准备)
- VC++ (二)类的访问级别
- 波特率、发送/接收时钟、波特率因子、传输距离
- 3号团队-团队任务4:每日例会(2018-11-28)
- Java之数组(下)
- 美国基金教父约翰博格传记(1)
- localtime选择00:00值不回显_配置OSPF的DR选择示例
- CC攻击原理及防范新思路
- Vue 引入 zepto
- C语言 - 详解回调函数
- 中望cad文字显示问号怎么办_CAD字体显示问号解决方法
- Kindle 2 初探
- Python3使用dbf模块读写dbf文件
- Python-Django毕业设计小斌美食网站(程序+LW)
热门文章
- CF 546E(最大流
- Maven本地库在哪?
- CSS的优先级和继承性
- qq飞车服务器维护中是什么,《QQ飞车》服务器对赛车平跑稳定性的影响攻略
- 借助传感器用计算机测速度实验题,专家分析2015年高考命题趋势 内容设计将再创新...
- 计算硼原子的基态能级的java程序
- 吸引纠缠的双白矮星和迭代收敛的神经网络
- 神经网络的收敛标准有最优值吗?
- 8. An Introduction to MCMC for Machine Learning (4)
- 【控制】《多智能体系统的协同群集运动控制》陈杰老师-第1章-绪论