题目链接:
http://www.51nod.com/Challenge/Problem.html#problemId=1186
1186 质数检测 V2
给出1个正整数N,检测N是否为质数。如果是,输出"Yes",否则输出"No"。
收起
输入
输入一个数N(2 <= N <= 10^30)输出
如果N为质数,输出"Yes",否则输出"No"。输入样例
17输出样例
Yes
第一种,适用于数据范围小的----直接暴力
This is the code:
#include<bits/stdc++.h>
using namespace std;
bool IsPrime(int x)
{
for(int i=2;i<=sqrt(x);++i)
if(x%i==0)
return false;
return true;
}
int main()
{
int n;
sccanf("%d",&n);
if(IsPrime(n))
printf("YES\n");
else
printf("NO\n");
return 0;
}
第二种,适用于1e18的数据范围 C++版的Miller_Rabin测试素数
This is the code:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL modular_exp(LL a,LL n,LL mod)
{
LL ret=1;
a%=mod;
while(n)
{
if(n&1)
ret=a*ret%mod,n--;
a=a*a%mod;
n>>=1;
}
return ret;;
}
bool miller_rabin1(LL n)//误差很大,直接使用费马定理判断
{
if(n==0||n==1)
return false;
if(n==2)
return true;
for(LL i=2; i<10; ++i)
{
LL a=rand()%(n-2)+2;
if(modular_exp(a,n,n)!=a)
return false;
}
return true;
}
LL gcd(LL a,LL b)//求最大公约数
{
return b?gcd(b,a%b):a;
}
LL multi(LL a,LL b,LL mod)//快速加法求模
{
LL ret=0;
while(b)
{
if(b&1)
ret=(ret+a)%mod,b--;
a=(a+a)%mod;
b>>=1;
}
return ret;
}
LL power(LL a,LL b,LL mod)
{
LL ret=1;
a%=mod;
while(b)
{
if(b&1)
ret=multi(ret,a,mod),b--;
a=multi(a,a,mod);
b>>=1;
}
return ret;
}
bool miller_rabin2(LL n)//费马定理和二次探测原理判断素数
{
if(n==2)
return true;
if(n<2||!(n&1))
return false;
LL m=n-1;
LL cnt=0;
while(!(m&1))
{
++cnt;
m>>=1;
}
LL Times=10;
for(LL i=0; i<Times; ++i)//Times==10
{
LL a=rand()%(n-1)+1;
LL x=power(a,m,n);
LL y=0;
for(LL j=0; j<cnt; ++j)
{
y=multi(x,x,n);
if(y==1&&x!=1&&x!=n-1)
return false;
x=y;
}
if(y!=1)
return false;
}
return true;
}
int main()
{
srand(time(NULL));
LL n;
scanf("%lld",&n);
if(miller_rabin1(n))
printf("YES\n");
else
printf("NO\n");
}
第三种 适用于大数 java大数版Miller_Rabin
This is the code:
import java.io.*;
import java.math.*;
import java.util.*;
import java.text.*;
public class Main{
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
BigInteger N;
N = cin.nextBigInteger();
if(IsPrime(N))
{
System.out.println("Yes");
}
else
System.out.println("No");
}
public static Boolean IsPrime(BigInteger num)
{
if(num.compareTo(BigInteger.valueOf(2)) == 0)
return true;
if((num.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(0)) == 0) || (num.compareTo(BigInteger.valueOf(1)) == 0))
return false;
BigInteger num_1 = num.subtract(BigInteger.valueOf(1));
int s = 0;
while(num_1.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(0)) == 0)
{
num_1 = num_1.divide(BigInteger.valueOf(2));
++ s;
}
Random ran = new Random();
for(int i = 0; i < 10; ++ i)
{
BigInteger a = BigInteger.valueOf(2);
BigInteger b = BigInteger.valueOf(Math.abs(ran.nextLong())).mod(num.subtract(BigInteger.valueOf(3)));
a = a.add(b);
BigInteger x = FastPowerMod(a,num_1,num);
if(x.compareTo(BigInteger.valueOf(1)) != 0 && x.compareTo((num.subtract(BigInteger.valueOf(1)))) != 0)
{
Boolean flag = false;
for(int j = 1; j < s; ++ j)
{
BigInteger t = x.multiply(x).mod(num);
if(t.compareTo(num.subtract(BigInteger.valueOf(1))) == 0)
{
flag = true;
break;
}
x = t;
}
if(flag)
continue;
return false;
}
}
return true;
}
public static BigInteger FastPowerMod(BigInteger a,BigInteger m,BigInteger n)
{
BigInteger ans = BigInteger.valueOf(1);
BigInteger tmp = a;
while(m.compareTo(BigInteger.valueOf(0)) == 1)
{
if(m.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(1)) == 0)
{
ans = ans.multiply(tmp).mod(n);
}
tmp = tmp.multiply(tmp).mod(n);
m = m.divide(BigInteger.valueOf(2));
}
return ans.mod(n);
}
}
第四种 适用于大数 java大数版 Miller_Rabin 集成的函数
This is the code:
import java.util.Scanner;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
BigInteger x;
x=cin.nextBigInteger();
if(x.isProbablePrime(1))
System.out.println("Yes");
else
System.out.println("No");
}
}