搬运我的洛谷题解,原题解创作日期:2026-09-14 21:16,链接:https://www.luogu.com.cn/article/md2ptl3v。

P17455 [GESP202609 五级] 哥德巴赫猜想

思路

分析

根据题意模拟即可。不过数据范围比较大,判断素数的时候不能直接用试除法,否则会超时,要用埃氏筛法或线性筛法预处理出素数表,才可以获得满分。

实现

先用埃筛预处理出一个布尔数组 isprime,这样后续判断一个数是否为素数时,可以直接查询,提高效率。

输入数字 $n$ 后,定义计数器 $cnt = 0$。

枚举 $i$,从 $2$ 到 $n / 2$。

::::info[为什么枚举到 n/2 ?]
因为题面规定 $10 = 3 + 7$ 和 $10 = 7 + 3$ 是同一种方案,循环到 $n / 2$ 就可以避免重复统计。
::::

对于每个数字 $i$,令 $j = n - i$,再判断 $i$ 和 $j$ 是否都为素数。

如果都是,则 $cnt$ 加一。

最后输出 $cnt$ 即可。

代码(有详细注释)

#include <bits/stdc++.h>
using namespace std;
const int mxn=1e6+5;
bool isprime[mxn];
void AiShiShai(){ //埃氏筛法模版预处理素数表。
    isprime[0]=isprime[1]=false;
    for(int i=2;i*i<=mxn;i++){
        if(isprime[i]){
            for(int j=i*i;j<mxn;j+=i){
                isprime[j]=false;
            }
        }
    }
}
int main(){
    memset(isprime,true,sizeof(isprime));//初始化为都为 true,假设每个数都是素数。
    AiShiShai();
    int n,cnt=0;
    cin>>n;
    for(int i=2;i<=n/2;i++){//循环到 n/2,因为 10 = 3 + 7 和 10 = 7 + 3 是同一种方案,这样可以避免重复。
        int j=n-i;//题目要求和,可以直接求出 n 减去 i 的差即可直接求出另一个数。
        if(isprime[i]==true && isprime[j]==true){
            cnt++;
        }
    }
    cout<<cnt;
	return 0;
}

总时间复杂度 $O(n \log \log n)$,空间复杂度 $O(n)$。在 $n \le 10^6$ 的范围内可以轻松通过。

本题解在写作完成后使用 DeepSeek 进行了润色。

保证作者本人贡献远大于 Deepseek。