让我们看看我们想要找到1到1000之间的所有数字,它们表示为两个素数的总和。例如8 = 3 + 5,24 = 13 + 11
现在可以通过迭代1到1000之间的素数列表在O(n ^ 2)中完成。
无论如何在O(n ^ 2)以内做同样的事情。是否有一种方法可以在线性时间内完成这项工作?
答案 0 :(得分:6)
对于我们现在知道的所有偶数,它们可以表示为2个素数的总和(参见Goldbach's conjecture)
对于所有奇数,如果它可以表示为2个素数的总和,则其中一个必须为2,另一个应为奇素数。
所以总数应为(1000/2 - 1)+(素数从3到997),
其中,
(1000/2 - 1)是系列4,6,8,10 ......
的总数(素数从3到997)是系列5(2 + 3),7(2 + 5),9(2 + 7),13(2 + 11)... 的总数p>
答案 1 :(得分:1)
制作1000个布尔值的数组p
。如果p[i]
为素数,则true
设为i
,否则设为false
。
然后O(N^2)
算法变得简单:在外部循环中遍历数字k
1到1000,然后在内部遍历大于x
的所有素数k
循环,并检查是否存在p[k-x]
为true
的素数:
for k in 1..1000
for x in primes greater than k
if (p[x-k])
print k can be represented as x plus (x-k)
break
我怀疑是否可以在一段时间内执行检查,对于1000个数字because computer-aided verification currently proceeds at a rather slow speeds,O(N)
的总运行时间为{{1}}。
答案 2 :(得分:0)
1! 1是一个很好的公式。首先,1000 + 1除以5x + 38.这是根据ATF定理。试试这个,你就会得到答案。
答案 3 :(得分:0)
import java.util.Scanner;
public class SumOfNPrmNos_2 {
public static void main(String[] args) {
int swap,sum=0;
Scanner sc=new Scanner(System.in);
System.out.println("Enter Number Range From ");
int small=sc.nextInt();
System.out.println("Enter Number Range To ");
int big=sc.nextInt();
for (int i =small+1 ; i<big; i++) {
char check='T';
for (int j=2 ; j<=Math.sqrt(i) ; j++){
if(i%j==0){
check='F';
break;
}
}
if(check=='T'){
sum=sum+i;
}
}
System.out.println("Sum Is : = "+sum);
}
}
答案 4 :(得分:0)
说明:在这里,我做了一个用户定义的函数,用于检查输入数字的素数。这个数字分为两部分,第一部分是num-1,第二部分是1(它们的总和等于num),现在第一个数字递减,第二个数字递增,直到它们都等于或大于,对于每个数字I查找它们是否都是素数,如果两者都是素数,则将break用于循环并打印这些数字。
#include<stdio.h>
int prime(int);
int main()
{
int num, r1, r2, i, j, c=0;
printf("enter number\n");
scanf("%d", &num);
for(i=num-1, j=1; i>=j; i--, j++) //this divides numb
{
r1=prime(i);
r2=prime(j);
if(r1==1 && r2==1)
{
printf("Numbers are %d and %d\n", i, j);
c++;
}
}
if(c==0)
printf("cannot be expressed as sum of primes\n");
}
int prime(int n)
{
int i;
for(i=2; i<=n; i++)
if(n%i==0)
break;
if(n==i)
return 1;
else
return 0;
}