素數問題三步曲_HDOJ2098

偶然間OJ上敲到一題素數問題便查詢了相關算法。對於該類問題我我的學習分爲三步曲:最笨的方法(TLE毫無疑問)->Eratosthrnes篩選法->歐拉線性篩選法php

針對HDOJ2098這道題進行代碼分析,發散性能夠解決其餘問題。算法

笨笨的方法(TLE)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    int a,b,n;
    while(1)
    {
        scanf("%d",&n);
//      printf("這是輸入的數:%d\n",n); 
        if(n==0) break;
        int i=1,sum=0;
        for(i=2;i<n/2;i++)
        {
            //判斷i,n-i二者是否都是素數
            int j=2,flag=0;
            for(j=2;j<=i/2;j++)
            {
                if(i%j==0)
                {
                    flag=1;
                    break;
                }
            }
//          printf("第一次判斷i是否爲素數結束\n"); 
            for(j=2;j<=(n-i)/2;j++)
            {
                if((n-i)%j==0||(n-i)==1)
                {
                    flag=1;
                    break;
                }
            }
//          printf("第二次判斷n-i是否爲素數結束\n");
            if(flag==0)
            {
//              printf("此時i和n-i都是素數:%d %d\n",i,n-i);
                sum++;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

Eratorsthenes篩選法(AC)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

#define MAX 100000
bool num[10000]={false,false,true};

int main()
{
    int n;
    int i=0,j=0;
    for(i=3;i<10000;i++)
    {
        //初始化全部的數都爲素數 
        num[i]=true;
    }
        
    //從2開始對全部素數的倍數置爲false 
    for(i=2;i*i<10000;i++)
    {
        if(num[i]==true)
        {
            for(j=i*i;j<10000;j+=i)
            {
                num[j]=false;
            }
        }
    }
    //檢測輸出全部比10000小的素數序列 
//  for(i=1;i<10000;i++)
//  {
//      if(num[i]==true)
//          printf("%d ",i);
//  }
    
    while(1)
    {
        int cnt=0;
        scanf("%d",&n);
        if(n==0) break;
    
        for(i=2;i<n/2;i++)
        {
            if(num[i]==true&&num[n-i]==true)
            {
                cnt++;
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

Eratorsthenes篩選法(複雜度nlogn)是素數問題中十分有名的解法:即要求N如下的全部爲素數的數有多少個?咱們須要檢查到sqrt(n)是否存在素數便可。學習

  1. 假設有一個篩子存放1~N的數。2 3 4 5 6 7 8 9 10 11 12 ...N
  2. 先將2的倍數篩選出去(必定不爲素數)2 3 5 7 9 11 13 17 19...N
  3. 將3的倍數篩選出去(必定不爲素數)2 3 5 7 11 13 17 19...N
  4. 即不斷對當前剩下的數列中最前面的數的倍數從數列中篩選出去,最後剩下的數列即爲全部比N小的素數序列。

歐拉線性篩選法

咱們能夠發如今Eratorthenes篩選法中,30,這個數,在215中被篩了一次,在56中又被重複篩了,因此對於此處能夠進行優化修改。可是我對於其中算法關鍵看了一會不是很懂,目前就暫時不寫吧。優化

相關文章
相關標籤/搜索