2262: Goldbach's Conjecture: Egypt sieve + foot forensics Goldbach conjecture

Subject to the effect

Topic Link
Goldbach conjecture: any even number greater than 4 can be split into the sum of two odd prime numbers.

For example: 3 + 5 = 8

20=3+17=7+13

42=5+37=11+31=13+29=19+23

Your task is to: verify the number is less than 10 ^ 6 to meet the Goldbach conjecture.

Output Format

For each test, the output of the form n = a + b, where a, b is an odd prime number.

If a plurality of sets satisfying the conditions a, b, b-a maximum output set. If there is no solution, the output of Goldbach's conjecture is wrong. (Note that there are periods).

Ideas analysis

I read a lot of problem solutions are playing table + enumeration, feeling a little Han Han, or do their best to write it, first of all think of the game play table very content, Egypt sieve method to find out. Because the number of prime numbers is fixed, once we take them all out into a single itemarray, instead of traversing all the numbers. There are about one million in the 80000 odd prime, look at the complexity of it / 10, at this time if the prime is relatively small, we can still play table, record all possible combinations of two odd prime, and direct output back, but here too , still have to deal with in turn, there are two main optimization

  • Every time we itemfind the first array is greater than the n/2value of our Look no more than here. For example 8=3+5, we checked the 3 over, could not be found 4 above.
  • Take feet, constant changes about the endpoint, the first odd prime satisfying meaning of the title of the largest difference is right.
#include<iostream>
#include<iomanip>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 1000005

bool prime[MAX];
vector<int> items;

int main() {
	//2是偶数,不是姬素数
	memset(prime, 1, sizeof(prime));
	prime[0] = prime[1] = prime[2] = 0;
	for (int i = 2; i < MAX; i++) {
		if (prime[i])items.push_back(i);
		if (i == 2 || prime[i])for (int j = 2 * i; j < MAX; j += i)prime[j] = 0;
 	}
	int n;
	while (cin >> n && n) {
		//找到一个和n/2最接近的数
		int pos = lower_bound(items.begin(), items.end(), n) - items.begin();
		int l = 0, r = pos - 1, sign = 0;
		while (r >= l) {//等于也是可以的
			int sum = items[l] + items[r];
			if (sum == n) {
				sign = 1; break;
			}
			if (sum > n)r--;
			else l++;
		}
		if (sign) printf("%d = %d + %d\n", n, items[l], items[r]);
		else cout << "Goldbach's conjecture is wrong." << endl;
	}
}
Published 186 original articles · won praise 13 · views 9326

Guess you like

Origin blog.csdn.net/csyifanZhang/article/details/105156867