给定一个正整数n,请你求出1~n中质数的个数。
输入格式
共一行,包含整数n。
输出格式
共一行,包含一个整数,表示1~n中质数的个数。
数据范围
1≤n≤106
输入样例:
8
输出样例:
4
//只适合n的数据较小时,一旦n过大,会超时
#include<iostream>
#include<cstdio>
using namespace std;
bool sum(int a)
{
for(int j=2;j<=a/j;j++)
{
if(a%j==0)
{return false;
break;
}
}return true;
}
int main()
{
int n,s=0;
cin>>n;
if(n==1)
s=0;
else
{ for(int i=2;i<=n;i++)
{
if(sum(i)==1)
s++;
}
}cout<<s<<endl;
return 0;
}
埃式筛法
n log(log 2 n)
“筛”这个动作的实现,可以使用一个bool型数组st来标记,如果i被筛掉,那么st[i]为true;否则,st[i]为 false。在程序开始时可以初始化st数组全为false。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000010;
int primes[N],cnt;
bool st[N];
void get_primes(int n)
{for(int i=2;i<=n;i++)
{
if(!st[i])
{
primes[cnt++]=i;//把质数存到数组里
//发现这样写也对
// primes[cnt++]=n;
for(int j=i+i;j<=n;j+=i)//把i的倍数筛掉从2i开始,每次加i
st[j]=true;
}
}
}
int main()
{
int n;
cin>>n;
get_primes(n);
cout<<cnt<<endl;
return 0;
}
**
//线性筛法
O(n)
n=1e7的时候比埃式算法快一倍
//算法核心:n仅仅会被其最小质因子筛去
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000010;
int prime[N],cnt;
bool st[N];//全局变量,初始值全部为0
void get_prime(int n)
{
for(int i=2; i<=n; i++)
{
if(!st[i]) prime[cnt++]=i;//把质数存到数组里
for(int j=0; prime[j]<=n/i; j++)
{
st[prime[j]*i]=true;//把质数pj的i倍都筛掉
if(i%prime[j]==0) break;//```````①
}
}
}
int main()
{
int n;
cin>>n;
get_prime(n);
cout<<cnt<<endl;
return 0;
}
对①处解释(pj代表prime[j])
i%pj==0 pj一定是i的最小质因子,pj也一定是pj*
i的最小质因子
i%pj !=0 pj一定小于i的所有质因子,所以pj也是pj*
i的最小质因子(最小哦)
对于一个合数x,假设pj是x的最小质因子,当i枚举到x/pj的时候,就筛去了