素数又称质数。一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数;否则称为合数。
求素数的方法
1. 枚举
bool isPrime(int n)
{
if(n==1)
return false;
for(int i=2;i<n;i++)
if(n%i==0)
return false;
return true;
}
2. 优化(只需判断到根号n即可)
bool isPrime(int n)
{
if(n==1)
return false;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return false;
return true;
}
3. 质数分布规律:大于等于5的质数一定和6的倍数相邻。例如5和7,11和13,17和19等等
bool isPrime(int n)
{
if(n==1)
return false;
if(n==2||n==3)
return true;
if(n%6!=1&&n%6!=5)
return false;
//在6的倍数的两侧的数也可能不是质数
for(int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0)
return false;
return true;
}
4. 埃式筛选法打表 O(nlogn)
const int N=100000;
int a[N];//a[i]=0表示i是素数
void makeatble(int n)
{
a[0]=a[1]=1;//0,1不是素数
for(int i=2;i<=n;i++)
if(!a[i]){
for(int j=i+i;j<=n;j+=i)
a[j]=1;
}
}
5.埃式筛选法中合数是作为素数的倍数被筛去的,显然,如果每个合数仅被它最小的质因子筛去,算法的效率会更高。这就是欧拉筛法
const int N=10000;
int prime[N+1]; //prime[0]存连续素数的个数,prime数组存储连续素数
void getPrime()
{
memset(prime,0,sizeof(prime));
for(int i=2;i<=N;i++){
if(!prime[i])
prime[++prime[0]]=i;
for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++){
prime[prime[j]*i]=1;
if(i%prime[j]==0)//如果prime[j]是i的最小质因子就跳出
break;
}
}
}
6、大素数判断
练习:
51Nod_1106 质数检测【水题】