给定非常大的数字N (> 150),任务是检查该数字是素数,半素数还是复合数。
例子:
Input: N = 90000000
Output: Not Prime
Explanation:
we have (N-1)%6 = 89999999%6 = 1 and
(N+1)%6 = 90000001%6 = 5
Since n-1 and n+1 is not divisible by 6
Therefore N = 90000000 is Not Prime
Input: N = 7894561
Output: Semi-Prime
Explanation:
Here N = 7894561 = 71*111191
Since 71 & 111191 are prime, therefore 7894561 is Semi Prime
方法:
- 可以看到,如果n是素数,则n + 1或n-1将被6整除。
- 如果存在数字n,使得n + 1和n-1都不可被6整除,则n不是质数
- 如果存在数字n使得n + 1或n-1被6整除,则n是质数或半质数
- 为了区分素数和半素数,使用以下方法:
- 如果N是半素数,
N = p*q ....................(1) where p & q are primes.
- 然后从哥德巴赫猜想:
p + q must be even i.e, p + q = 2*n for any positive integer n
- 因此,求解p&q将得到
p = n - sqrt(n2 - N) q = n + sqrt(n2 - N)
- 令n 2 – N为完美平方,然后
n2 - N = m2, .................(2) for any positive integer m
- 求解方程(1)和(2),我们得到
m = (q-p)/2 n = (p+q)/2
- 现在,如果等式(1)和(2)在某个点满足,则存在一对(p,q),使得数N为半素数,否则N为素数。
- 如果N是半素数,
- 公式(2)形成勾股三重体
- 预期的解决方案在图表上有所不同
伪代码:
- 输入一个数N,并且如果N – 1和N + 1不是整除6然后数量N不是素数。否则是素数或半素数
- 如果n-1或n + 1被6整除,则在范围(sqrt(N)+ 1,N)中进行迭代,并找到一个对(p,q),使得p * q = N的计算公式如下:
p = i - sqrt(i*i - N) q = n/p where i = index in range(sqrt(N) + 1, N)
- 如果p * q = N,则数字N为半素数,否则为质数
下面是上述方法的实现:
Java
import static java.lang.Math.sqrt;
public class Primmefunc {
public static void prime(long n)
{
int flag = 0;
// checking divisibilty by 6
if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0) {
System.out.println("Not Prime");
}
else {
// breakout if number is perfect square
double s = sqrt(n);
if ((s * s) == n) {
System.out.println("Semi-Prime");
}
else {
long f = (long)s;
long l = (long)((f * f));
// Iterating over to get the
// closest average value
for (long i = f + 1; i < l; i++) {
// 1st Factor
long p = i - (long)(sqrt((i * i) - (n)));
// 2nd Factor
long q = n / p;
// To avoid Convergence
if (p < 2 || q < 2) {
break;
}
// checking semi-prime condition
if ((p * q) == n) {
flag = 1;
break;
}
// If convergence found
// then number is semi-prime
else {
// convergence not found
// then number is prime
flag = 2;
}
}
if (flag == 1) {
System.out.println("Semi-Prime");
}
else if (flag == 2) {
System.out.println("Prime");
}
}
}
}
public static void main(String[] args)
{
// Driver code
// Entered number should be greater
// than 300 to avoid Convergence of
// second factor to 1
prime(8179);
prime(7894561);
prime(90000000);
prime(841);
prime(22553);
prime(1187);
}
//written by Rushil Jhaveri
}
CPP
#include
using namespace std ;
void prime(long n)
{
int flag = 0;
// checking divisibilty by 6
if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0)
{
cout << ("Not Prime") << endl;
}
else
{
// breakout if number is perfect square
double s = sqrt(n);
if ((s * s) == n)
{
cout<<("Semi-Prime")<
Python3
def prime(n):
flag = 0;
# checking divisibilty by 6
if ((n + 1) % 6 != 0 and (n - 1) % 6 != 0):
print("Not Prime");
else:
# breakout if number is perfect square
s = pow(n, 1/2);
if ((s * s) == n):
print("Semi-Prime");
else:
f = int(s);
l = int(f * f);
# Iterating over to get the
# closest average value
for i in range(f + 1, l):
# 1st Factor
p = i - (pow(((i * i) - (n)), 1/2));
# 2nd Factor
q = n // p;
# To avoid Convergence
if (p < 2 or q < 2):
break;
# checking semi-prime condition
if ((p * q) == n):
flag = 1;
break;
# If convergence found
# then number is semi-prime
else:
# convergence not found
# then number is prime
flag = 2;
if (flag == 1):
print("Semi-Prime");
elif(flag == 2):
print("Prime");
# Driver code
if __name__ == '__main__':
# Entered number should be greater
# than 300 to avoid Convergence of
# second factor to 1
prime(8179);
prime(7894561);
prime(90000000);
prime(841);
prime(22553);
prime(1187);
# This code is contributed by 29AjayKumar
C#
using System;
public class Primmefunc
{
public static void prime(long n)
{
int flag = 0;
// checking divisibilty by 6
if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0)
{
Console.WriteLine("Not Prime");
}
else
{
// breakout if number is perfect square
double s = Math.Sqrt(n);
if ((s * s) == n)
{
Console.WriteLine("Semi-Prime");
}
else
{
long f = (long)s;
long l = (long)((f * f));
// Iterating over to get the
// closest average value
for (long i = f + 1; i < l; i++)
{
// 1st Factor
long p = i - (long)(Math.Sqrt((i * i) - (n)));
// 2nd Factor
long q = n / p;
// To avoid Convergence
if (p < 2 || q < 2)
{
break;
}
// checking semi-prime condition
if ((p * q) == n)
{
flag = 1;
break;
}
// If convergence found
// then number is semi-prime
else
{
// convergence not found
// then number is prime
flag = 2;
}
}
if (flag == 1)
{
Console.WriteLine("Semi-Prime");
}
else if (flag == 2)
{
Console.WriteLine("Prime");
}
}
}
}
// Driver code
public static void Main(String[] args)
{
// Entered number should be greater
// than 300 to avoid Convergence of
// second factor to 1
prime(8179);
prime(7894561);
prime(90000000);
prime(841);
prime(22553);
prime(1187);
}
}
// This code is contributed by 29AjayKumar
输出:
Prime
Semi-Prime
Not Prime
Semi-Prime
Semi-Prime
Prime
时间复杂度: O(N)