孪生素数法
这个方法的数学证明略微繁琐,这里就不加以展开(主要是我懒得码字 )所以就直接搬大佬博客了
reference
主要思路就是:
一个大于3的数如果想要成为素数,那它必须要在6的附近
而在6附近的数又不一定是素数,这说明,6附近的数的集合大于素数集合。而在小学一年级的时候我们就知道,每个合数都可以写成若干个素数的乘积,那么在判断一个数是否为素数的时候就可以把一个数除以6附近的两个数以达到优化目的
接下来上代码
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
bool is_prime(int n)
{
if(n<=1)return false;//特判
if(n==2||n==3)return true;//特判
if(n%6!=1&&n%6!=5)return false;
for(int i=5;i<=(int)sqrt(n);i+=6){
if(n%i==0||n%(i+2)==0)return false;
}
return true;
}
素数表(埃及筛法)
这是一个超级简单的方法 思路如下:
素数的倍数都不是素数,那么直接上代码
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 1e6+10;//具体大小由题目而定
vector<int> prime;
int main()
{
prime.resize(maxn,1);
prime[0]=prime[1]=0;
for(int i=2;i*i<=prime.size();i++){
if(prime[i]){
for(int j=2*i;j<=prime.size();j+=i){
prime[j]=0;
}
}
}
return 0;
}
模板题 洛谷P3912素数个数
素数表直接过,暴力不失优雅
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1e8+10;
bool prime[maxn];
int main()
{
int n;scanf("%d",&n);
int s=n;s--;
for(int i=2;i<=n;i++){
if(prime[i]==0){
for(int j=i*2;j<=n;j+=i){
if(!prime[j]){
prime[j]=1;
s--;
}
}
}
}
printf("%d",s);
return 0;
}