给定一个非常大的数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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。