素数筛
给定一个正整数 nn,请你求出 1∼n1∼n 中质数的个数。
输入格式
共一行,包含整数 nn。
输出格式
共一行,包含一个整数,表示 1∼n1∼n 中质数的个数。
数据范围
1≤n≤1061≤n≤106
输入样例:
8
输出样例:
4
素数:只有1和本身的因子成为素数,也称质数
求素数的一种方法试除法:按照其定义来,枚举1到n-1没有可以被整除的数,优化为1到sqrt(n)
埃氏筛法:
从2开始,把每一个2的倍数筛掉,3的倍数晒掉,(4被筛了),5的倍数筛掉....
这样留下来的就都是素数,因为没有被筛掉,所以令这个数为p不是2到p-1的数的倍数,也就是没有约数,那就是素数:
优化:可以把每个质数的倍数筛掉就可以了
因为一个合数可以质因数分解,把质数的倍数筛掉,那筛去的就都是合数,也就是一个合数必然被前面的质数给筛掉,所以剩下来的也就都是素数
#include<iostream> using namespace std; const int N=1e6+10; int prime[N],cnt;//存素数及其个数 bool st[N];//筛子 void primes(int n) { for(int i=2;i<=n;i++)//从2开始筛 { if(st[i]) continue;//合数就跳过,筛质数的倍数 prime[cnt++]=i;//存质数及其个数 for(int j=i+i;j<=n;j+=i) st[j]=true;//筛掉 } cout<<cnt<<endl; } int main(){ int n; cin>>n; primes(n); return 0; }
线性筛法:
核心:n只会被最小质因子筛掉
用最小质因子来筛,每一个数都只有一个最小质因子,所以所有的合数都会被筛掉,所以是线性的
#include<iostream> using namespace std; const int N=1e6+10; int prime[N],cnt;//存素数及其个数 int st[N];//筛子 void primes(int n) { for(int i=2;i<=n;i++)//筛所有的n以内的素数 { if(!st[i]) prime[cnt++]=i;//如果是素数就存起来 for(int j=0;prime[j]<=n/i;j++)//从0开始枚举素数,等价于prime[j]*i<=n,当然啊,总共才到n个 { st[prime[j]*i]=true; if(i%prime[j]==0) break;//如果此时的素数被i整除,那这个素数就是i的最小质因子 } } } int main(){ int n; cin>>n; primes(n); cout<<cnt<<endl; return 0; }
这个我不好表述...不会的时候看acw最高赞题解吧,写的很清楚
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具