Goldbach's Conjecture_POJ 2262

来源:互联网 发布:手机如何共享wifi网络 编辑:程序博客网 时间:2024/06/05 08:42

题目

题目链接http://poj.org/problem?id=2262

Goldbach's Conjecture
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 45238 Accepted: 17237

Description

In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conjecture: 
Every even number greater than 4 can be 
written as the sum of two odd prime numbers.

For example: 
8 = 3 + 5. Both 3 and 5 are odd prime numbers. 
20 = 3 + 17 = 7 + 13. 
42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23.

Today it is still unproven whether the conjecture is right. (Oh wait, I have the proof of course, but it is too long to write it on the margin of this page.) 
Anyway, your task is now to verify Goldbach's conjecture for all even numbers less than a million. 

Input

The input will contain one or more test cases. 
Each test case consists of one even integer n with 6 <= n < 1000000. 
Input will be terminated by a value of 0 for n.

Output

For each test case, print one line of the form n = a + b, where a and b are odd primes. Numbers and operators should be separated by exactly one blank like in the sample output below. If there is more than one pair of odd primes adding up to n, choose the pair where the difference b - a is maximized. If there is no such pair, print a line saying "Goldbach's conjecture is wrong."

Sample Input

820420

Sample Output

8 = 3 + 520 = 3 + 1742 = 5 + 37

Source

Ulm Local 1998

思路

1.  素数判定。判断是否存在两个和为 n 的素数

2. 素数判定有O(n^-2)的朴素素数测试法,和O(n*lglgn)的文氏筛法,这里采用的是文氏筛法。


细节

1.  看着n <= 10^6, 本想着节约空间,就没采用数组保存素数,用的set,结果TLE,实在想不出还能怎么优化。。。最后看的大神们的题解,才知道自己用set保存素数,查找操作是Omega(lgn),所以总的复杂度是O(nlgn),10^6本来就有点悬。(想不通直接素数判定的O(n*n^-2)都能过。。难道是我算错复杂度了哭)。。。而用数组保存的话,查找操作O(1),总的复杂度是O(n),算是空间换时间。

2. 这道题收货就是,要学会估算复杂度,数据结构要选择合适。。。


代码
这是我set保存的代码,提交后TLE

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <set>using namespace std;#define MAX_N 1000000vector<int> data;set<int> prime;bool is_prime[MAX_N+1];void prime_sieve(int n);int main(){//#define LOCAL#ifdef LOCALfreopen("data.in", "r", stdin);#endif // LOCALint N;int largest = 0;set<int>::iterator it;vector<int>::iterator it_data;    while ( scanf("%d", &N) && N != 0) {    data.push_back(N);    largest = max(largest, N);    }prime_sieve(largest+100);int da;for (it_data = data.begin(); it_data != data.end(); it_data++) {da = *it_data;it = prime.lower_bound(da);// O(nlgn)for ( ; *it >= da/2; it--) {if (binary_search(prime.begin(), prime.end(), da-(*it))) {printf("%d = %d + %d\n", da, da - (*it), (*it) );break;}}if (*it < da/2) {cout << "Goldbach's conjecture is wrong." << endl;}    }    return 0;}void prime_sieve(int n) {for (int i = 0; i <= n; i++) is_prime[i] = true;is_prime[0] = is_prime[1] = false;for (int i = 2; i <= n; i++) {if (is_prime[i]) {prime.insert(i);for (int j = 2*i; j <= n; j += i) is_prime[j] = false;}}}

这是我参照别人题解写的,复杂度 O(n)
#include <iostream>#include <cstdio>using namespace std;typedef long long ll;#define MAX_N 1000000int prime[MAX_N+100];bool is_prime[MAX_N+100];ll prime_sieve(ll n);int main(){//#define LOCAL#ifdef LOCALfreopen("data.in", "r", stdin);#endif // LOCALll N;prime_sieve(MAX_N+10);    while ( scanf("%lld", &N) && N != 0) {ll i;for (i = N-1; i >= N/2; i--) {     //复杂度 O(n)if (is_prime[i] && is_prime[N-i]) {printf("%lld = %lld + %lld\n", N, N-i, i);break;}}if (i < N/2) cout << "Goldbach's conjecture is wrong." << endl;    }    return 0;}ll prime_sieve(ll n) {ll p = 0;for (ll i = 0; i <= n; i++) is_prime[i] = true;is_prime[0] = is_prime[1] = false;for (ll i = 2; i <= n; i++) {if (is_prime[i]) {prime[p++] = i;for (ll j = 2*i; j <= n; j += i) is_prime[j] = false;}}return p;}


0 0
原创粉丝点击