4393: 【入门】筛素数(2136)
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:59
解决:30
题目描述
输入一个整数 ,请问 范围内有多少个素数?
输入
一个整数 ()
输出
输出 范围内素数的个数。
样例输入 复制
20
样例输出 复制
8
提示
埃筛
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
bool f[N]; //标记素数,false表示是素数,true表示不是
int primes[N],k=0; //存储所有的素数
int n;
int main(){
cin>>n;
//特判特殊的数
f[0]=true;
f[1]=true;
//循环所有的数,逐个判断
for(int i=2;i<=n;i++) {
//如果i是素数,i的倍数不是素数
if(!f[i]){
k++;
primes[k]=i;
//将i的倍数标记为不是素数
for(int j=i+i;j<=n;j=j+i){
f[j]=true; //标记不是素数
}
}
}
cout<<k;
return 0;
}
埃筛(不用数组存起来)
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
bool f[N]; //标记素数,false表示是素数,true表示不是
int primes[N],k=0; //存储所有的素数
int n;
int main(){
cin>>n;
//特判特殊的数
f[0]=true;
f[1]=true;
k=n-1;
//循环所有的数,逐个判断
for(int i=2;i*i<=n;i++) {
//如果i是素数,i的倍数不是素数
if(!f[i]){
//k++;
//primes[k]=i;
//将i的倍数标记为不是素数
for(int j=i+i;j<=n;j=j+i){
if(!f[j]) {
f[j]=true; //标记不是素数
k--;
}
}
}
}
cout<<k;
return 0;
}
线性筛
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
bool f[N]; //标记素数,false表示是素数,true表示不是
int primes[N],k=0; //存储所有的素数
int n;
/*
线性筛:每个合数只被自己的最小质因数筛除
比如:6在埃筛能被2筛除,又能被3筛除
我们希望在线性筛中,6仅仅被最小质因子,也就是2筛除
*/
int main(){
cin>>n;
//特判特殊的数
f[0]=true;
f[1]=true;
//循环所有的数,逐个判断
for(int i=2;i<=n;i++) {
//如果i是素数,i的倍数不是素数
if(!f[i]){
k++;
primes[k]=i;
}
//每个合数,只能被自己的最小质因子筛除
//j循环的是primes数组
for(int j=1;i*primes[j]<=n;j++){
f[i*primes[j]]=true; //将该数筛掉
//如果i%primes[j]==0
//i*primes[j+1]%primes[j]==0
if(i%primes[j]==0) break;
}
}
cout<<k;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000010
bool is_prime[MAXN];
int prime[MAXN];
//埃筛
int Er_Sieve(int n){
int tot=0;
memset(is_prime,1,sizeof(is_prime));
is_prime[1] = is_prime[0] = 0;
for(int i = 2;i <= n;i++){
if(!is_prime[i]) continue;
prime[++tot] = i; //prime[]存储了[1,n]的所有质数
for(int j = i*2; j <= n; j+=i)
is_prime[j]=0; //j为合数
}
return tot;
}
//线性筛(欧拉筛)
int Eu_Sieve(int n){
int tot=0;
memset(is_prime,1,sizeof(is_prime));
is_prime[0] = is_prime[1] = 0;
for(int i = 2; i <= n; i++){
if(is_prime[i])
prime[++tot] = i; //prime[]存储了[1,n]的所有质数
for(int j = 1; j <= tot && prime[j]*i <= n; j++){ //关键一
is_prime[prime[j]*i] = 0;
if(i%prime[j] == 0) break;// 关键二
}
}
return tot;
}
int main(){
int n;
cin>>n;
cout<<Er_Sieve(n);
return 0;
}