目錄
題目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;
}