素数
质数(prime number)又称素数,有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。
任意大于等于5的素数都与6的倍数相邻。
如果n是一个合数,那么n一定有一个不超过sqrt(n)的素因子。
判断一个数是否是素数的思路
在一般领域,对正整数n,如果用2到sqrt(n)之间的所有整数去除,均无法整除,则n为质数。
方法一
bool isprime(int x) { for (int i=2;i<x;i++) { if (x%i==0) return false; } return true; }
方法二
bool isprime(int x) { for (int i=2;i*i<=x;i++) { if (x%i==0) return false; } return true; }
筛素数法
筛素数法可以比枚举法节约极大量的时间(n为所求最大值,m为≤n的质数个数,那么枚举需要O(m*n)的时间复杂度,而筛素数法为O(m+n),显然m<<n,所以时间效率有很大提升。)。如1000000的数据范围,用筛素数法可在2s内解决。
思路:建立一个bool型数组M,若已知一个数M[k]是质数,那么其i(i为正整数)倍M[k*i]必然为合数,可将其去除。
埃氏筛法(时间复杂度O(nlogn))
bool Isprime[Maxn]; void prime(int x) { memset(Isprime,true,sizeof(Isprime)); Isprime[1]=0; for (int i=2;i<=x;i++) { for (int j=2;i*j<=x;j++) Isprime[i*j]=0; } return; }
欧氏筛素数(时间复杂度O(n))
int prime[maxn],tot; bool vis[maxn]; void isprime(){ for(int i=2;i<maxn;i++){ if(!vis[i]){ prime[tot++]=i; } for(int j=0;j<tot;j++){ if(i*prime[j]>maxn) break;//判断是否越界 vis[i*prime[j]]=1;//筛掉合数 if(i%prime[j]==0) break;//判断因子是否包含素因子 } } }