筛出 100 以内素数表,对每个偶数升序枚举第一个加数,首个两数皆素数的即为最小拆分。
OJ: roj
题目 ID: 1157
难度:入门
标签:入门枚举素数判定数学python
创建: 2026-09-29 21:14
更新: 2026-10-05 03:53
题目描述
对 n=p+q,其中
思路
先用埃氏筛一次性标好
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 21:16
# update_at: 2026-09-29 21:16
LIMIT = 100 # 题目只拆 6~100 的偶数
def sieve(limit: int) -> list[bool]:
"""埃氏筛:is_prime[x] 为 True 表示 x 是素数。"""
is_prime = [False, False] + [True] * (limit - 1)
for p in range(2, int(limit ** 0.5) + 1):
if is_prime[p]:
is_prime[p * p::p] = [False] * ((limit - p * p) // p + 1)
return is_prime
def solve() -> None:
is_prime = sieve(LIMIT)
# 偶数只能拆成"奇+奇"(2+偶数必非素数),从小到大试奇数,
# 第一个让两数都是素数的 p 就是题面要求的"最小的第一加数"。
out: list[str] = []
for n in range(6, LIMIT + 1, 2):
p = next(p for p in range(3, n, 2) if is_prime[p] and is_prime[n - p])
out.append(f"{n}={p}+{n - p}")
print('\n'.join(out))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 03:51
* update_at: 2026-10-05 03:51
*/
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 105;
bool is_prime[MAXN]; // is_prime[i] = true 表示 i 是素数
// 埃氏筛,标记 [2, MAXN-1] 范围内的素数
void sieve() {
memset(is_prime, true, sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
for (int i = 2; i * i < MAXN; i++) {
if (is_prime[i]) {
for (int j = i * i; j < MAXN; j += i) {
is_prime[j] = false;
}
}
}
}
int main() {
sieve();
// 对 6~100 的每个偶数,升序枚举第一个加数,首个两边皆素数的即为最小拆分
for (int n = 6; n <= 100; n += 2) {
for (int p = 3; p <= n / 2; p += 2) {
int q = n - p;
if (is_prime[p] && is_prime[q]) {
printf("%d=%d+%d\n", n, p, q);
break;
}
}
}
return 0;
}