AcWing算法提高课-5.1.1哥德巴赫猜想

宣传一下 算法提高课整理

CSDN个人主页:更好的阅读体验

Start

原题链接
题目描述

哥德巴赫猜想的内容如下:

任意一个大于 4 4 4 的偶数都可以拆成两个奇素数之和。

例如:

8 = 3 + 5 8 = 3 + 5 8=3+5
20 = 3 + 17 = 7 + 13 20 = 3 + 17 = 7 + 13 20=3+17=7+13
42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23 42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23 42=5+37=11+31=13+29=19+23

现在,你的任务是验证所有小于一百万的偶数能否满足哥德巴赫猜想。

输入格式

输入包含多组数据。

每组数据占一行,包含一个偶数 n n n

读入以 0 0 0 结束。

输出格式

对于每组数据,输出形如 n = a + b,其中 a , b a,b a,b 是奇素数。

若有多组满足条件的 a , b a,b a,b,输出 b − a b-a ba 最大的一组。

若无解,输出 Goldbach's conjecture is wrong.

数据范围

输入最多包含 50006 50006 50006 组数据。
6 ≤ n < 1 0 6 6 \le n < 10^6 6n<106

输入样例:
8
20
42
0
输出样例:
8 = 3 + 5
20 = 3 + 17
42 = 5 + 37

思路

显然这是一道关于质数的题。

观察数据范围,我们发现,需要复杂度最高是 O ( n ) O(n) O(n) 的算法才能过。

所以我们考虑使用线性筛预处理出 1 ∼ 1 0 6 1 \sim 10^6 1106 的所有质数,然后从第一个开始枚举。
如果 p ∈ P p \in \mathbb{P} pP n − p ∈ P n-p \in \mathbb{P} npP,则输出。( P \mathbb{P} P 为质数集)

最后我们考虑无解的情况。

虽然哥德巴赫猜想没有被证明,但是通过我们暴力算法的验证,我们发现在 1 0 6 10^6 106 的范围内的哥德巴赫猜想 一定有解

所以即使你不考虑无解情况照样 AC \color{green}\text{AC} AC

但是作者因为考虑到题解的严谨性,还是写了无解情况的判断。具体细节请看代码。

算法时间复杂度
AC Code

C + + \text{C}++ C++

#include <iostream>

using namespace std;

const int N = 1e6 + 10;

int n;
int primes[N], cnt;
bool st[N];

void get_primes() // 线性筛质数
{
	st[1] = true; // 这里特殊处理1不是质数(我们用false表示质数)
    for (int i = 2; i < N; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= N / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int main()
{
    get_primes(); // 处理 1 ~ 1e6 所有质数
    
    while (cin >> n && n)
    {
        bool flag = 0;
        for (int i = 1; primes[i] <= n; i ++ )
            if (!st[n - primes[i]]) // 如果n-primes[i]是质数就输出
            {
                printf("%d = %d + %d\n", n, primes[i], n - primes[i]);
                flag = 1;
                break;
            }
        if (!flag) puts("Goldbach's conjecture is wrong."); // 无解情况
    }
    
    return 0;
}

228aa7bed3e021faf24cf8560d3e47bb.gif

最后,如果觉得对您有帮助的话,点个赞再走吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河依旧长明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值