1. 程式人生 > 其它 >AcWing 1292. 哥德巴赫猜想

AcWing 1292. 哥德巴赫猜想

題目傳送門

埃篩時間複雜度

\(O(nlg(n)lg(n))\)

質數個數定理

\(1\sim n\)之間質數的個數是\(\frac{ln(n)}{n}\)

調和級數

\(1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}=lgn+L\)
上面的式子被稱為調和級數,其中\(L\)是一個常數,被稱為尤拉常數,是無理數還是有理數還沒有被證明出來,大約值是\(0.577\),大概率是一個無理數。

其實也可以記一下:\(\frac{1}{2}+\frac{1}{3}+\frac{1}{5}+\frac{1}{7}+\frac{1}{11}...+\frac{1}{n}\)

(\(n\)是質數)這個計算的時間複雜度為\(loglogn\),這個時間複雜度是很牛\(B\)的,可以視為\(O(1)\)

實現程式碼

#include <bits/stdc++.h>
using namespace std;

//尤拉篩
const int N = 1e6 + 10;
int primes[N], cnt; // primes[]儲存所有素數
bool st[N];         // st[x]儲存x是否被篩掉
void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] * i <= n; j++) {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}
int main() {
    get_primes(N - 1); //不能到N,因為陣列下標從0開始!要不會越界~

    int n;
    while (scanf("%d", &n), n) { //用逗號比用 && 少一個輸入字元~
        for (int i = 1;; i++) {  //不斷列舉每個奇數質數,不用上界,因為認為哥德巴赫猜想是正確的,肯定有解
            int a = primes[i];   //放過數字2
            int b = n - a;       //差值
            if (!st[b]) {        //差值也是質數
                printf("%d = %d + %d\n", n, a, b);
                break;
            }
        }
    }

    return 0;
}