POJ 2262 Goldbach's Conjecture(…

题意:哥德巴赫猜想,任意大于6的偶数,都能被任意两个奇素数以和的形式替代。

odd prime numbers 奇素数 (除2外所有的素数)

even number 偶数

 

分析:题目难度其实并不大,但是极易出错,连续几次都是TLE,主要还是一开始的思路有点问题

    开始的思路:用一个数组存储3~1000000中的所有的素数,然后再通过循环判定。

               一般的题目这个思路确实行的通,但是这类题,这么大的数字明显就是想卡人TLE的,所以需要变通。

变通的方式有两种,

一种就是优化选择素数的方法,素数判定法,线性筛选法之类的

另外一种,就是不用数组存储素数,直接用的时候判断。这样的话,将素数放进数组的时间就可以省掉了。

 

按照第二种方法的AC代码:

 (248K,574M)

 没对素数的选择做什么的优化,由于要求,b-a要最大值,肯定一个从最小开始,一个从最大开始,然后通过代码中的循环。i从小到大增长,如果,i和n-i都是素数的话,就可以终止循环了,i+n-i肯定等于n。这样就求出了题目要求的a和b,按标准输出就行了。。。。。。。。。开始还TLE了好多次…………

C++语言:
#include<iostream>
using namespace std;

bool odd_prime_numbers( int n)
{
    int i;
    for( i = 3; i * i <=n; i = i + 2)
        if(n % i == 0) return 0;
    return 1;
}

int main()
{
    int i ,n;
    while( cin >>n &&n != 0)
    {
        for( i = 3; i <=n / 2; i = i + 2)             //要用i<=n/2做个停止的标志。
            if( odd_prime_numbers( i) && odd_prime_numbers(n - i))
                break;
        cout <<n << " = " << i << " + " <<n - i << endl;
    }
    return 0;
}

 

收获:

 1.基本方法:判断n能否被2~sqrt(n)中的数整除
2.素数判断法:由算术基本定理得来,其实就是基本方法的一个优化,任何一个大于2的整数都能表示成两个素数的乘积,所以要求1000内的所有素数,只要先求出100内的所有素数即可,然后判断n能否被2~sqrt(n)中的所有素数整除即可。  这种思想还是值得借鉴一下的。(有个使用前提就是提前要知道所有sqrt(n)一下的所有素数)
3.筛选法
筛选法的基本思想,就是一个删除的思想,如果用基本方法的话,例如判断个数据就要从2一直扫到sqrt(n),每一个数的检测都需要扫一遍,很耗时间,如果研究的数据不大的时候,筛选法和基本方法的差别并不明显。但是一旦数据比较大的话,筛选法的优势就能,明显的展现出来。

例如有:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25这样组数

1倍不算
遍历一遍,删掉2的倍数(标记):得2 3 5 7 9 11 13 15 17 19 21 23 25

遍历一遍,删掉3的倍数:得2 3 5 7 11 13 17 19 23 25

遍历一遍,删除5的倍数,得2 3 5 7 11 13 17 19 23

……

以poj2262为例

 

 

C++语言:
#include <stdio.h>
#define MAX 1000001

int prime [ MAX ] = { 0 }; // 0为素数,1不是素数

void getprime()
{
    int i , j;
    for ( i = 2; i < MAX / 2; i ++)
    {
        if ( ! prime [ i ]) // 加上判断减少时间
        {
            for ( j = 2; i * j < MAX; j ++)
            {
                prime [ j * i ] = 1; // 是某一个数的倍数        
            }
        }
    }
    prime [ 0 ] = prime [ 1 ] = 1;
}

int main()
{
    int n , i , has;
   
    getprime();
    has = 0;
    while ( scanf( "%d" , &n) == 1 && n != 0) {
        for ( i = 3; i <= n / 2; i += 2) { // 只有奇数才可能是素数
            if ( prime [ i ] == 1 || prime [n - i ] == 1)
            {
                continue;
            } else {
                printf( "%d = %d + %d \n " , n , i , n - i);
                break;
            }
        }
        if ( i > n / 2)
            printf( "Goldbach's conjecture is wrong. \n ");
    }
       
    return 0;
}

 

比较详细的关于素数判断的讲解:http://wxdlut.blog.163.com/blog/static/128770158200910129412537/

你可能感兴趣的:(POJ 2262 Goldbach's Conjecture(…)