题解 UVA543 【Goldbach's Conjecture】

这道题在#10200. 「一本通 6.2 练习 3」Goldbach's Conjecture也有。

先分析题,验证强哥德巴赫猜想。

首先我们发现要用到素数,而且是多个素数,所以显然要用筛法,因为想巩固一下欧拉筛,所以我直接写的欧拉筛,埃筛应该也可以。

呢么就是暴力枚举小于\(\frac{n}{2}\)的素数,因为两个素数一定是一个大于\(\frac{n}{2}\)、一个小于\(\frac{n}{2}\),并且我们是从小到大枚举所以第一对符合的素数就是结果。

呢么枚举一个素数后另一个数也就确定了,我们只要判断是不是素数就行。因为已经有了素数表,所以只要在素数二分查找即可,但是我懒,直接用lower_bound()就过了。

对于lower_bound()我们只要判断二分出来的数是不是我们要找的数,就可以判断有没有这个数。

#include 
using namespace std;


const int N = 1e6+5;
int n = 1e6,num,prime[N],cnt;
bool vis[N],flag;


inline int read()
{
    register int x = 0;
    register char ch = getchar();
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >= '0' && ch <= '9')
    {
        x = (x<<3) + (x<<1) + ch-'0';
        ch = getchar();
    }
    return x;
}


inline void primes()
{
    for(register int i = 2;i <= n;i ++)
    {
        if(!vis[i]) prime[++cnt] = i;
        for(register int j = 1;j <= cnt &&i*prime[j] <= n;j ++)
        {
            vis[i*prime[j]] = i;
            if(i%prime[j] == 0) break;
        }
    }
}

int main()
{
    primes();
    
    while(1)
    {
        num = read();flag = 0;
        if(num == 0) break;
        for(register int i = 1;prime[i] <= num/2 && i <= cnt;i ++)
        {
            register int j = num - prime[i];
            if(j != *lower_bound(prime,prime+cnt,j)) continue;
            flag = 1;
            printf("%d = %d + %d\n",num,prime[i],j);
            break;
        }
        if(flag) continue;
        puts("Goldbach's conjecture is wrong.");
    }
}

你可能感兴趣的:(题解 UVA543 【Goldbach's Conjecture】)