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;
}
}
}
}
相關文章
- 素數篩 : Eratosthenes 篩法, 線性篩法
- Prime Path(POJ - 3126)【BFS+篩素數】
- 素數篩
- 尤拉篩線性篩質數
- 洛谷P3383 【模板】線性篩素數
- 素數篩(埃氏篩法與尤拉篩)
- 線性篩合數
- 素數個數 <埃式篩 && 尤拉篩>
- 尤拉篩(線性篩)
- 【數論】素數篩法
- Sum of Consecutive Prime Numbers POJ - 2739(線性尤拉篩+尺取法)
- [演算法]: 素數篩法演算法
- 線性篩質數 題解 luoguP3383
- Diff-prime Pairs(思維+素數篩)AI
- wenbao與篩法素數及判斷模板
- 平凡的函式 線性篩積性函式函式
- 質數篩
- 第六章 數學問題 ----------6.13 素數的篩法(第十萬零二個素數)
- Android開商品屬性篩選與商品篩選Android
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- 增補部落格 第二十篇 python 篩法求素數Python
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- 尤拉素數篩選與命令列傳參啟動C程式命令列C程式
- 信奧日記——數論(快速冪、埃氏篩、尤拉篩)
- 約束定理+質數篩
- 篩選法求質數
- xgboost 特徵選擇,篩選特徵的正要性特徵
- 杜教篩
- 尤拉篩
- 質數判斷、質因子分解、質數篩
- 教你excel篩選手機號碼公式和excel篩選正常電話號碼Excel公式
- excel怎麼篩選?教你一個簡單粗暴的篩選技巧Excel
- excel批量篩選重複人名 excel怎麼篩選相同的名字Excel
- excel批次篩選重複人名 excel怎麼篩選相同的名字Excel
- 動態篩選
- jQuery 篩選方法jQuery
- 外包篩選心得
- EFCore 使用FluntApi配置 全域性查詢篩選器API
- XGBoost 輸出特徵重要性以及篩選特徵特徵