對於每個輸入的偶數 n (4 ≤ n < 2^15 = 32768),計算有多少對本質不同的質數對 (p1, p2) 滿足 p1 + p2 = n 且 p1 ≤ p2。輸入以 0 結束。
最大 n = 32767,質數上限同此。用篩法 O(N log log N) 生成所有質數及 isPrime[] 布爾數組。
對於每個 n:
p1 從 2 到 n/2。isPrime[n - p1] 為真,則 (p1, n-p1) 為一組合法分解,計數器++。n/2,自動保證 p1 ≤ p2,不重複計算。#include <bits/stdc++.h>
using namespace std;
const int MAXN = 32768;
bool isPrime[MAXN];
vector<int> primes;
void sieve() {
fill(begin(isPrime), end(isPrime), true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < MAXN; ++i) {
if (isPrime[i]) {
for (int j = i * i; j < MAXN; j += i) isPrime[j] = false;
}
}
for (int i = 2; i < MAXN; ++i) if (isPrime[i]) primes.push_back(i);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
sieve();
int n;
while (cin >> n && n != 0) {
int count = 0;
for (int p : primes) {
if (p > n / 2) break;
if (isPrime[n - p]) count++;
}
cout << count << "\n";
}
return 0;
}
import java.util.*;
public class Goldbach {
static final int MAXN = 32768;
static boolean[] isPrime = new boolean[MAXN];
static List<Integer> primes = new ArrayList<>();
static {
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < MAXN; i++) {
if (isPrime[i]) {
for (int j = i * i; j < MAXN; j += i) isPrime[j] = false;
}
}
for (int i = 2; i < MAXN; i++) if (isPrime[i]) primes.add(i);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextInt()) {
int n = sc.nextInt();
if (n == 0) break;
int count = 0;
for (int p : primes) {
if (p > n / 2) break;
if (isPrime[n - p]) count++;
}
System.out.println(count);
}
}
}
O(MAXN log log MAXN) ≈ 3e4,極快。n/2,質數個數 ~ n/ln(n),最多 ~3000 次循環,O(π(n))。O(MAXN)。輸入:
6
10
12
0
輸出:
1 (6 = 3+3)
2 (10 = 3+7, 5+5)
1 (12 = 5+7)
bitset 或 long[] 壓縮空間,提高緩存命中。ans[n],查詢 O(1)。