本来是在做容斥原理的题,既然碰到求a~b内与n互质的数的个数,就顺便将与素数相关的知识整理一遍。
1、输入数n,判断是否为素数的一般方法:
#include<iostream>
using namespace std;
int main()
{
int n,i;
bool bo=true;
cin>>n;
if (n==1) bo=false;
else for (i=2;i*i<=n;i++)
if (n%i==0)
{
bo=false;
break;
}
cout<<bo<<endl;
return 0;
}
2、对上述方法进行优化:
#include<iostream>
using namespace std;
int main()
{
int n,i;
bool bo=true;
cin>>n;
if (n==1||(n%2==0&&n!=2)) bo=false; //先把大于2的偶数的情况排除
else for (i=3;i*i<=n;i+=2) //如果一个数不能被2整除,当然就不能被大于2的偶数整除,所以只需判断3,5,7······
if (n%i==0)
{
bo=false;
break;
}
cout<<bo<<endl;
return 0;
}
3、在学完素数筛选法求素数后掌握了一种新方法。
算术基本定理
任何一个大于1的自然数N,都可以唯一分解成有限个质数的乘积
根据上述定理,如果我们已经知道不大于正整数n的开方的素数有哪些,那么验证n为素数时,只需要判断这些素数是不是n的约数,而不需要每次“+2”判断能否被整除。特别是对于判断多个很大的数是不是素数时比较管用,先找出sqrt(max) 范围内的素数,然后判断,比起对每个数每次“+2”判断省事很多。当然,找素数时需要用到效率较高的素数筛选法(请参考:http://blog.csdn.net/yzj577/article/details/38147433)。
参考代码:
//用素数筛选验证素数
#include<iostream>
using namespace std;
#define N 50001
bool isprime[N];
int prime[5500];
int main()
{
int n,i,j;
memset(isprime,true,sizeof(isprime));
int num=0;
prime[num++]=2;
for (i=3;i<=N;i+=2)
{
if (isprime[i])
{
prime[num++]=i;
for (j=i+i;j<=N;j+=i) isprime[j]=false;//找到一个素数,标记它的倍数就不是素数
}
}
cin>>n;
bool bo=true;
if(n==1)bo=false;
else for (i=0;prime[i]*prime[i]<=n;i++)
{
if (n%prime[i]==0)
{
bo=false;
break;
}
}
cout<<bo<<endl;
return 0;
}