1. 程式人生 > >PAT Basic 1007. 素數對猜想 (20) (C語言實現)

PAT Basic 1007. 素數對猜想 (20) (C語言實現)

, CSDN內容暫時不更新(將來有計劃更新), 請前往連結檢視最新內容. 歡迎star 我的repo

題目

讓我們定義 d_n 為:d_n = p_{n+1} - p_n,其中 p_i 是第i個素數。顯然有 d_1=1 且對於n>1有 d_n 是偶數。“素數對猜想”認為“存在無窮多對相鄰且差為2的素數”。

現給定任意正整數N (< 10^5),請計算不超過N的滿足猜想的素數對的個數。

輸入格式:每個測試輸入包含1個測試用例,給出正整數N。

輸出格式:每個測試用例的輸出佔一行,不超過N的滿足猜想的素數對的個數。

輸入樣例
20

輸出樣例
4

思路

大致思路:驗證[1-N]每一個數n是否為素數,如果n和n-2同時為素數,則找到一對“孿生素數”

驗證某一個數n為素數時,只需驗證n能否被小於sqrt(n)的素數整除即可,題目限制最大數為10^5,其平方根約為320(不到),320以內的素數可以粗略計算應該能保證在100個之內,估算方法[1]可以使用320/ln(320)=55.4(實際是65個),當然這是粗略估算的粗略估算,具體要在執行時用100 000驗證一下沒有段錯誤來保證。

結論:使用長度為100的陣列記錄前一百個素數,即可檢驗100 000以內所有數是否是素數。

記錄孿生素數也可以只用三個標記數來記錄連續三個數n, n + 1, n + 2的素數情況。

程式碼實現:

初始化:100個素數裡初始化便寫入前兩個2,3,從4開始驗證,這樣不影響邊界情況(N=5之前沒有孿生素數),避免了2這樣沒有更小的素數可供驗證的情況,並且進入迴圈即可開始驗證孿生素數。

結果參考:

N孿生素數對數
1~40
204
1008
100035
10000205
1000001224

程式碼

#include <stdio.h>
int main()
{
    int N;
    scanf("%d", &N);
    /* record three successive numbers if they are prime numbers, start from 2, 3, 4 */
    int iPrimeMinus2 = 1, iPrimeMinus1 = 1, iPrime;
    /* record the prime numbers before sqrt(10^5) */
    int primes[100] = {2, 3};
    int paircount = 0;
    int primecount = 2;

    for (int i = 4; i <= N; i++)
    {
        iPrime = 1;
        /* test if i is a prime number */
        for(int j = 0; primes[j] * primes[j] <= i; j++) if(i % primes[j] == 0)
        {
            iPrime = 0;
            break;
        }
        /* i is a prime number */
        if(iPrime == 1)
        {
            if(primecount < 100)    primes[primecount++] = i;
            if(iPrimeMinus2 == 1)   paircount++;    /* a prime pair found */
        }
        /* change the flags */
        iPrimeMinus2 = iPrimeMinus1;
        iPrimeMinus1 = iPrime;
    }
    printf("%d", paircount);

    return 0;
}