质数:又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数。
英文:prime number
判定一个数是否是质数的基础方法
bool Prime1(int n)
{
if (n<2) return false;
if (n==2) return true;
if (n%2==0) return false;
for (int i=3; i<n; i+=2)
if(n%i==0) return false;
return true;
}
进化版,限制条件i*i<n
bool Prime2(int n)
{
if (n<2) return false;
if (n==2) return true;
if (n%2==0) return false;
for (int i=3; i*i<=n; i+=2){ //注意求因数个数的题不加等号,另判
if(n%i==0) return false;
}
return true;
}
一般筛法求素数:
有些数被筛了多次,如30在2*15时一次,3*10时又一次
void Prime3(int n)
{
memset(a,true,sizeof(a)); //假设初始均为素数
a[0]=false; a[1]=false;
for (int i=2; i*i<n; i++){
if(a[i]){ //从i*i开始而不是i*2,效率更高
for(int k=i*i; k<n; k+=i)
a[k]=false;
}
}
}
线性筛法求素数:
原理:一个合数x假设可以表示成
x = A * b A为合数,b为质数
A = y * m y为质数,合数A 还有更小的质因数y
x = y * b * m 则x可以表示成最小的质因数y和一个大合数的乘积
例如12在 2 x 6 即 i = 6 时筛,而不再 3 x 4 时筛,当 i = 4 时 i 有质因数 2
每个合数都 在其最小质因数 处被标记
int p[manx];
int num=0; //质数的个数
int a[manx]={1,1}; //except 0,1
void Prime4(int n)
{
for (int i=2; i<n; i++){
if (a[i]==0) p[num++]=i; //储存质数
for (int j=0; j<num && i*p[j]<n; j++){
a[i*p[j]]=1;//合数为1,p[j]是i*p[j]的最小质因数
if (i%p[j]==0) break; //i可以表示成小于p[j]的质数之积
}
}
}
做了几道简单题: hdu1262 http://blog.csdn.net/fsmm_blog/article/details/58238269
hdu2136 http://blog.csdn.net/fsmm_blog/article/details/58233775 hdu2161