hiho251 哥德巴赫猜想

目錄

題目1 : 歌德巴赫猜想

1.題是什麼?

2.思路   

3.ac代碼


題目1 : 歌德巴赫猜想

時間限制:10000ms
單點時限:1000ms
內存限制:256MB

描述

哥德巴赫猜想認爲“每一個大於2的偶數,都能表示成兩個質數之和”。
給定一個大於2的偶數N,你能找到兩個質數P和Q滿足P<=Q並且P+Q=N嗎?

輸入

一個偶數N(4 <= N <= 1000000)

輸出

    輸出P和Q。如果有多組解,輸出P最小的一組。

樣例輸入

10

樣例輸出

3 7

1.題是什麼?

    從前有個很牛的數學家叫哥德巴赫,他猜想任意一個大於2的偶數都可以由小於它的兩個質數相加得到,雖然他到死也沒能證明,我們也到現在爲止還沒證明出來,不過我們可以放心的是這個猜想在int範圍內是完全成立的,不信邪的可以運行以下代碼跑跑試試

#include <stdio.h>

    迴歸正題,就是要你一個給定的1e6以內的偶數n,要你輸出那兩個和爲n的質數a,b,有多種情況時只輸出較小數最小的那一組數據。

2.思路   

    首先這道題素數埃式篩法是少不了的,不瞭解埃式篩法的先移步我的這個博客:素數處理-埃式篩法.

    現在我們利用埃式篩法篩選出n以內的所有素數於prime數組,然後遍歷prime,通過flag實現O(1)檢查n-prime[i]是否是素數,第一個滿足條件的prime[i]與n-prime[i]自然就是答案

3.ac代碼

#include <stdio.h>

// 位操作求素數 
const int maxn=1e6+1;
int prime[maxn],primenum;
int flag[maxn/32+1];//數組大小實際縮小8倍 

//預處理出t以內的所有素數及flag
void wei_prime(int t){
 primenum=0;
 flag[0]|=3;
 for(int k=1;k<=t/32+1;k++) flag[k]=0;
 for(int i=2;i<=t;i++){
        if(!((flag[i/32]>>(i%32))&1)){
            for(int j=i*2;j<=t;j+=i) flag[j/32]|=(1<<(j%32));
            prime[primenum++]=i;
        } 
    }
}

void solve(){
    int n,rest;
    scanf("%d",&n);
    wei_prime(n);
    for(int i=0;i<primenum;i++){
        rest=n-prime[i];
        if(!((flag[rest/32]>>(rest%32))&1)){         
            printf("%d %d\n",prime[i],rest);
            return;
         }
    }
}

int main(){
    solve();
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章