这道题在#10200. 「一本通 6.2 练习 3」Goldbach's Conjecture也有。
先分析题,验证强哥德巴赫猜想。
首先我们发现要用到素数,而且是多个素数,所以显然要用筛法,因为想巩固一下欧拉筛,所以我直接写的欧拉筛,埃筛应该也可以。
呢么就是暴力枚举小于\(\frac{n}{2}\)的素数,因为两个素数一定是一个大于\(\frac{n}{2}\)、一个小于\(\frac{n}{2}\),并且我们是从小到大枚举所以第一对符合的素数就是结果。
呢么枚举一个素数后另一个数也就确定了,我们只要判断是不是素数就行。因为已经有了素数表,所以只要在素数二分查找即可,但是我懒,直接用lower_bound()
就过了。
对于lower_bound()
我们只要判断二分出来的数是不是我们要找的数,就可以判断有没有这个数。
#include <bits/stdc++.h>
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.");
}
}