素数又称质数。一个大于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;
-
}
-
}
-
}
练习:
51Nod_1106 质数检测【水题】
转载来源 : https://blog.csdn.net/SongBai1997/article/details/81604338
素数又称质数。一个大于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;
-
}
-
}
-
}
练习:
51Nod_1106 质数检测【水题】
转载来源 : https://blog.csdn.net/SongBai1997/article/details/81604338