2018.04.22ACM--训练题(计蒜客)B

Description:


Goldbach's conjecture is one of the oldest and best-known unsolved problems in number theory and all of mathematics. It states:


Every even integer greater than 2 can be expressed as the sum of two primes.


The actual verification of the Goldbach conjecture shows that even numbers below at least 1e14 can be expressed as a sum of two prime numbers. 


Many times, there are more than one way to represent even numbers as two prime numbers. 


For example, 18=5+13=7+11, 64=3+61=5+59=11+53=17+47=23+41, etc.


Now this problem is asking you to divide a postive even integer n (2<n<2^63) into two prime numbers.


Although a certain scope of the problem has not been strictly proved the correctness of Goldbach's conjecture, we still hope that you can solve it. 


If you find that an even number of Goldbach conjectures are not true, then this question will be wrong, but we would like to congratulate you on solving this math problem that has plagued humanity for hundreds of years.


Input:


The first line of input is a T means the number of the cases.


Next T lines, each line is a postive even integer n (2<n<2^63).


Output:


The output is also T lines, each line is two number we asked for.


T is about 100.


本题答案不唯一,符合要求的答案均正确
样例输入


1
8
样例输出


3 5



翻译:

描述:




哥德巴赫猜想是数论和数学中最古老,最着名的未解决问题之一。它指出:

每个大于2的偶数都可以表示为两个素数的总和。

哥德巴赫猜想的实际验证表明,至少1e14以下的偶数可以表示为两个素数的和。

很多时候,将偶数表示为两个素数的方法不止一种。

例如,18 = 5 + 13 = 7 + 11,64 = 3 + 61 = 5 + 59 = 11 + 53 = 17 + 47 = 23 + 41等

现在这个问题要求你将正整数n(2 <n <2 ^ 63)分成两个素数。

虽然一定范围的问题没有被严格证明哥德巴赫猜想的正确性,但我们仍然希望你能解决它。

如果你发现偶数的哥德巴赫猜想不是真的,那么这个问题就会出错,但是我们要祝贺你解决这个数百年来困扰人类的数学问题。

输入:

第一行输入是T意味着案件的数量。

接下来的T行,每行是一个正整数n(2 <n <2 ^ 63)。

输出:

输出也是T线,每行都是我们要求的两个数字。

T是大约100。


预处理前1e6范围内的素数(素数定理保证2^63内无解概率几乎为0)

对于每次询问n,逐个暴力这些素数ai,利用素数判定判断n-ai是否是素数。

提交的很多的超时和错误原因是因为未考虑到大数据(大于2^62、小于2^63)时的溢出。

由于数据范围是long long,素数判定时存在左移位,故在素数判定可采用unsigned long long防止溢出。


import java.util.*;
import java.math.*;
public class Main {
	public static void main(String args[]) {
		int[] oddPrime = new int[1500];
		int numPrime = 0;
		for(int i=2;i<=10000;i++) {
			int flag=0;
			for(int j=2;j*j<=i;j++) {
				if(i%j==0) {
					flag=1;
					break;
				}
			}
			if(flag==0) {
				oddPrime[numPrime]=i;
				numPrime ++;
			}
		}
		Scanner cin = new Scanner(System.in);
		int T = cin.nextInt();
		while(T>0) {
			BigInteger x = cin.nextBigInteger();
			for(int i=0;i<numPrime;i++) {
				BigInteger delta = x.subtract(BigInteger.valueOf(oddPrime[i]));
				if(delta.isProbablePrime(100)) {
					System.out.println(oddPrime[i]+" "+delta.toString());
					break;
				}
			}
			T--;
		}
		cin.close();
	}
}

猜你喜欢

转载自blog.csdn.net/xiaorui98/article/details/80141072
今日推荐