我正在尝试第一次实施米勒 - 拉宾。我的代码给出了所有测试用例的正确答案,我试过但仍然在SPOJ上给出了错误的答案。 问题陈述:如果输入的数字为素数,我应该打印“是”否则为“否” 请帮忙:
问题链接:http://www.spoj.com/problems/PON/
CODE:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define LL long long
LL expo(LL a,LL b,LL c)
{
LL x=1,y=a;
if(b==0)
return 1;
while(b)
{
if(b%2==1)
x=(x*y)%c;
y=(y*y)%c;
b=b/2;
}
return x;
}
int main()
{
LL t,s,x,a,n,prime,temp;
scanf("%lld",&t);
srand(time(NULL));
while(t--)
{
scanf("%lld",&n);
if(n<2)
puts("NO");
else if(n==2)
puts("YES");
else if(n%2==0)
puts("NO");
else
{
s=n-1;
prime=1;
while(s%2==0)
s=s/2;
for(int i=0;i<20;i++)
{
a=rand()%(n-1)+1;
x=expo(a,s,n);
temp=s;
while((temp!=n-1)&&(x!=1)&&(x!=n-1))
{
x=(x*x)%n;
temp*=2;
}
if((x!=n-1)&&(temp%2==0))
{
prime=0;
break;
}
}
if(prime==0)
puts("NO");
else
puts("YES");
}
}
return 0;
}
答案 0 :(得分:0)
请注意,puts
会在您提供的字符串中附加换行符'\n'
。您可以尝试使用printf
。
答案 1 :(得分:0)
我认为您对 s 和 d 的计算不正确:
function isStrongPseudoprime(n, a)
d := n - 1; s := 0
while d % 2 == 0
d := d / 2; s := s + 1
t := powerMod(a, d, n)
if t == 1 return ProbablyPrime
while s > 0
if t == n - 1 return ProbablyPrime
t := (t * t) % n
s := s - 1
return Composite
我在我的博客{@ 3}}中讨论了Miller-Rabin方法。
答案 2 :(得分:0)
由于整数溢出,你得到错误的答案,因为你将2个长数相乘而不能在一个长long类型中保留。
这是python中解决问题的解决方案
import random
_mrpt_num_trials = 25 # number of bases to test
def is_probable_prime(n):
assert n >= 2
# special case 2
if n == 2:
return True
# ensure n is odd
if n % 2 == 0:
return False
# write n-1 as 2**s * d
# repeatedly try to divide n-1 by 2
s = 0
d = n - 1
while True:
quotient, remainder = divmod(d, 2)
if remainder == 1:
break
s += 1
d = quotient
assert(2 ** s * d == n - 1)
def try_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2 ** i * d, n) == n - 1:
return False
return True
for _ in range(_mrpt_num_trials):
a = random.randrange(2, n)
if try_composite(a):
return False
return True
for i in range(int(input())):
a = int(input())
if is_probable_prime(a):
print("YES")
else:
print("NO")