POJ 2262 Goldbach's Conjecture (求解素數的一般篩和線性篩)
Goldbach's Conjecture
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 40944 | Accepted: 15664 |
Description
In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conjecture:
For example:
Today it is still unproven whether the conjecture is right. (Oh wait, I have the proof of course, but it is too long to write it on the margin of this page.)
Anyway, your task is now to verify Goldbach's conjecture for all even numbers less than a million.
Every even number greater than 4 can be
written as the sum of two odd prime numbers.
For example:
8 = 3 + 5. Both 3 and 5 are odd prime numbers.
20 = 3 + 17 = 7 + 13.
42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23.
Today it is still unproven whether the conjecture is right. (Oh wait, I have the proof of course, but it is too long to write it on the margin of this page.)
Anyway, your task is now to verify Goldbach's conjecture for all even numbers less than a million.
Input
The input will contain one or more test cases.
Each test case consists of one even integer n with 6 <= n < 1000000.
Input will be terminated by a value of 0 for n.
Each test case consists of one even integer n with 6 <= n < 1000000.
Input will be terminated by a value of 0 for n.
Output
For each test case, print one line of the form n = a + b, where a and b are odd primes. Numbers and operators should be separated by exactly one blank like in the sample output below. If there is more
than one pair of odd primes adding up to n, choose the pair where the difference b - a is maximized. If there is no such pair, print a line saying "Goldbach's conjecture is wrong."
Sample Input
8
20
42
0
Sample Output
8 = 3 + 5
20 = 3 + 17
42 = 5 + 37
Source
Ulm Local 1998
題目連結:http://poj.org/problem?id=2262
題目大意:把一個數分成兩個奇素數的和,要求b-a的差最大
題目分析:題是水題,從小到大列舉即可,主要是借這道題說明一下求解素數的兩個篩法
普通的素數篩時間複雜度O(nlogn)
線性篩時間複雜度O(n)
普通篩沒什麼好說的,主要是線性篩的break那裡,比如12這個數,在普通篩的時候12要被2和3都篩一次,顯然這種多餘的操作會增加時間複雜度,線性篩中一個數字只被它最小的素因子篩掉,比如12只被2篩掉,當i等於6的時候2*6==12篩掉12,這時候6%2==0可以break了,如果不break,那麼6還會把18篩掉,此時是通過6*3來篩掉18,可是顯然18最小的素因子是2,所以當i列舉到9的時候有9*2==18,這樣18就又被篩了一次,因此在i等於6的時候不用拿6去篩18,下面用公式來說明:
當prime[j]是i的因子時,設i=prime[j]*k,因為素因子從小到大列舉,所以prime[j]是i的最小素因子,此時i已經無需再去剔除prime[j']*i (j'>j) 形式的合數了,因為prime[j']*i可以寫成prime[j']*(prime[j]*k)=prime[j]*(prime[j']*k),也就是說所有的prime[j']*i將會被將來的某個i'=prime[j']*k剔除掉,當前的i已經不需要了。比如先前舉的例項
本題程式碼:
題目連結:http://poj.org/problem?id=2262
題目大意:把一個數分成兩個奇素數的和,要求b-a的差最大
題目分析:題是水題,從小到大列舉即可,主要是借這道題說明一下求解素數的兩個篩法
普通的素數篩時間複雜度O(nlogn)
void get_prime()
{
memset(prime, true, sizeof(prime));
prime[1] = 0;
for(int i = 2; i * i <= MAX; i++)
if(prime[i])
for(int j = i * i; j <= MAX; j += i)
prime[j] = 0;
}
線性篩時間複雜度O(n)
void get_prime()
{
pnum = 0;
memset(prime, true, sizeof(prime));
prime[0] = false;
prime[1] = false;
for(int i = 2; i < MAX; i++)
{
if(prime[i])
p[pnum ++] = i;
for(int j = 0; j < pnum && i * p[j] < MAX; j++)
{
prime[i * p[j]] = false;
if(i % p[j] == 0)
break;
}
}
}
普通篩沒什麼好說的,主要是線性篩的break那裡,比如12這個數,在普通篩的時候12要被2和3都篩一次,顯然這種多餘的操作會增加時間複雜度,線性篩中一個數字只被它最小的素因子篩掉,比如12只被2篩掉,當i等於6的時候2*6==12篩掉12,這時候6%2==0可以break了,如果不break,那麼6還會把18篩掉,此時是通過6*3來篩掉18,可是顯然18最小的素因子是2,所以當i列舉到9的時候有9*2==18,這樣18就又被篩了一次,因此在i等於6的時候不用拿6去篩18,下面用公式來說明:
當prime[j]是i的因子時,設i=prime[j]*k,因為素因子從小到大列舉,所以prime[j]是i的最小素因子,此時i已經無需再去剔除prime[j']*i (j'>j) 形式的合數了,因為prime[j']*i可以寫成prime[j']*(prime[j]*k)=prime[j]*(prime[j']*k),也就是說所有的prime[j']*i將會被將來的某個i'=prime[j']*k剔除掉,當前的i已經不需要了。比如先前舉的例項
本題程式碼:
#include <cstdio>
#include <cstring>
int const MAX = 1000005;
int p[MAX];
bool prime[MAX];
int pnum;
void get_prime()
{
pnum = 0;
memset(prime, true, sizeof(prime));
prime[0] = false;
prime[1] = false;
for(int i = 2; i < MAX; i++)
{
if(prime[i])
p[pnum ++] = i;
for(int j = 0; j < pnum && i * p[j] < MAX; j++)
{
prime[i * p[j]] = false;
if(i % p[j] == 0)
break;
}
}
}
// void get_prime()
// {
// memset(prime, true, sizeof(prime));
// prime[1] = 0;
// for(int i = 2; i * i <= MAX; i++)
// if(prime[i])
// for(int j = i * i; j <= MAX; j += i)
// prime[j] = 0;
// }
int main()
{
get_prime();
int n;
while(scanf("%d", &n) != EOF && n)
{
for(int i = 3; i <= n / 2; i += 2)
{
if(prime[i] && prime[n - i])
{
printf("%d = %d + %d\n", n, i, n - i);
break;
}
}
}
}
相關文章
- 數論線性篩總結 (素數篩,尤拉函式篩,莫比烏斯函式篩,前n個數的約數個數篩)函式
- Find Terrorists(素數篩選+素因子分解)Error
- [演算法]: 素數篩法演算法
- Diff-prime Pairs(思維+素數篩)AI
- 平凡的函式 線性篩積性函式函式
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- Android開商品屬性篩選與商品篩選Android
- JQuery選擇器——可見性篩選選擇器和屬性篩選選擇器jQuery
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- 尤拉素數篩選與命令列傳參啟動C程式命令列C程式
- ACdream 1112 Alice and Bob (博弈&&素數篩選優化)優化
- 約束定理+質數篩
- Codeforces 893E Counting Arrays:dp + 線性篩 + 分解質因數 + 組合數結論
- 杜教篩
- jQuery type屬性值篩選input元素jQuery
- HDU 4542 小明系列故事——未知剩餘系 (DFS 反素數 篩子預處理)
- xgboost 特徵選擇,篩選特徵的正要性特徵
- POJ 2886 Who Gets the Most Candies?(線段樹+反素數)
- 教你excel篩選手機號碼公式和excel篩選正常電話號碼Excel公式
- jQuery 篩選方法jQuery
- 動態篩選
- excel批量篩選重複人名 excel怎麼篩選相同的名字Excel
- excel批次篩選重複人名 excel怎麼篩選相同的名字Excel
- excel怎麼篩選?教你一個簡單粗暴的篩選技巧Excel
- EFCore 使用FluntApi配置 全域性查詢篩選器API
- js根據input標籤的type屬性篩選元素JS
- 高效的知識閱讀和資訊篩選技巧
- 抓取全表掃描的表,篩選和分析
- excel如何篩選出自己想要的部分 excel表格如何篩選特定內容Excel
- XGBoost 輸出特徵重要性以及篩選特徵特徵
- 海量資料“一鍵篩選”,比Excel還好用的篩選功能,更便捷了!Excel
- JS中的陣列過濾,從簡單篩選到多條件篩選JS陣列
- 用q實現篩法求1-n的質數
- Pandas根據篩選條件對指定excel列進行篩選!神器!Excel
- Excel如何篩選出自己想要的資料 excel怎麼篩選出需要的內容Excel
- jQuery 篩選&文件處理jQuery
- Min25篩詳解
- excel怎麼快速篩選?Excel