【题目来源】
https://www.acwing.com/problem/content/870/
【题目描述】
给定一个正整数 n,请你求出 1∼n 中质数的个数。
【输入格式】
共一行,包含整数 n。
【输出格式】
共一行,包含一个整数,表示 1∼n 中质数的个数。
【数据范围】
1≤n≤10^6
【输入样例】
8
【输出样例】
4
【算法分析】
普通的素数筛法,即将给定的数 n 以内的所有数 x 的倍数 kx(k≥2) 都筛掉。
显然由下图可知,同一个数可能被多个素数重复筛掉。如下图中的 6、12 被重复筛掉。
这需要优化,欧拉筛便是一种素数的线性筛法。原理是让每个合数只被它的最小质因数筛掉,这样每个合数只会被筛选一次。
【算法代码】
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int p[maxn];
bool st[maxn];
int cnt;
void getNum(int n) {
for(int i=2; i<=n; i++) {
if(!st[i]) p[cnt++]=i;
for(int j=0; p[j]*i<=n; j++) {
st[p[j]*i]=true;
if(i%p[j]==0) break;
}
}
}
int main() {
int n;
cin>>n;
getNum(n);
cout<<cnt<<endl;
return 0;
}
/*
in:8
out:4
*/
【参考文献】
https://zhuanlan.zhihu.com/p/494328631
https://www.acwing.com/solution/content/7950/