POJ 2262 Goldbach's Conjecture (求解素数的一般筛和线性筛)
来源:互联网 发布:蹭网器密码破解软件 编辑:程序博客网 时间:2024/06/06 00:38
Goldbach's Conjecture
Time Limit: 1000MS Memory Limit: 65536KTotal 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
820420
Sample Output
8 = 3 + 520 = 3 + 1742 = 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; } } }}
0 0
- POJ 2262 Goldbach's Conjecture (求解素数的一般筛和线性筛)
- poj 2262 Goldbach's Conjecture 【素数筛】
- poj 2262 Goldbach's Conjecture 素数筛
- POJ 2262-Goldbach's Conjecture(素数筛)
- Goldbach`s Conjecture 【素数线性筛法】
- poj 2262 Goldbach's Conjecture 【素数筛法】
- poj2262 Goldbach's Conjecture(线性素数筛+暴力枚举)
- POJ 2262 Goldbach's Conjecture(素数表)
- poj 2262 Goldbach's Conjecture 素数 水题
- POJ 2262 Goldbach's Conjecture(素数相关)
- POJ 2262 Goldbach's Conjecture 素数筛选
- POJ 2262 Goldbach's Conjecture(素数)
- POJ 2262 Goldbach's Conjecture 简单的素数
- POJ Goldbach's Conjecture(素数筛~欧拉筛法)
- lightoj 1259 - Goldbach`s Conjecture 【素数筛】
- POJ 2262 Goldbach's Conjecture ( 筛选法求素数 )
- POJ 2262/ ZOJ 1951:Goldbach\'s Conjecture - 筛法打素数表
- 素数水题 POJ 2262 Goldbach's Conjecture
- iOS应用内置付费In-App Purchases入门
- 设计模式之装饰模式
- 【Leetcode】Reorder List
- C++11 标准新特性: 右值引用与转移语义
- 76. Minimum Window Substring
- POJ 2262 Goldbach's Conjecture (求解素数的一般筛和线性筛)
- node在windows下node-gyp编译可能会出现的问题
- SharedPreferences
- 【Android优化】最强ListView优化方案
- 老程序员的忠告(转)
- Linux 虚拟机 快捷键
- HDU 1509:Windows Message Queue【优先队列】
- OpenGL着色器语言3.4-3.8
- 队列的入队和出队操作