1. 程式人生 > >POJ3006-Dirichlet's Theorem on Arithmetic Progressions

POJ3006-Dirichlet's Theorem on Arithmetic Progressions

一個個 全部 clu 個數 amp 序列 sin 篩法 The

題意:

設一個等差數列,首元素為a,公差為d

現在要求輸入a,d,n ,要求找出屬於該等差數列中的第n個素數並輸出

思路:空間換時間是個主旋律。素數表的生成用素數篩選法。方法是從2開始,對每個目前還標記為素數的數(初始情況下每個數都標記為素數),把它的所有倍數都標記為非素數。這些掃描過去後,一直沒被標記的(即保持為素數的)就是所有的素數。

之後的事情就比較簡單了,對等差序列中的每個數一個個去查預先生成的素數表,一直數到第n個素數輸出即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4
using namespace std; 5 #define N 1000000 6 7 int prime[N];//裝素數 8 bool vis[N];//記錄該值是否已被訪問 9 10 void dabiao()//歐拉篩法打表 11 { 12 int i,j,cnt=0;//cnt為素數個數 13 14 memset(prime,0,sizeof(prime)); 15 memset(vis,true,sizeof(vis));//先全部假設為素數 16 vis[0]=vis[1]=false; 17 18 for (i=2;i<=N;i++)
19 { 20 if (vis[i])//找到一個素數 21 { 22 prime[cnt++]=i; 23 } 24 25 for (j=0;j<cnt&&i*prime[j]<=N;j++) 26 { 27 vis[i*prime[j]]=false;//打上標記 28 29 if (i%prime[j]==0)//停止篩選,因為在以後的合數倍篩選中會篩到 30 {
31 break; 32 } 33 } 34 } 35 } 36 37 void test() 38 { 39 int i; 40 for (i=0;i<100;i++) 41 { 42 printf("%2d",vis[i]); 43 } 44 } 45 46 int main() 47 { 48 int i,cnt; 49 dabiao(); 50 // test(); 51 52 while (1) 53 { 54 int a,d,n; 55 56 scanf("%d %d %d",&a,&d,&n); 57 cnt=0; 58 59 if (a==0&&d==0&&n==0) 60 { 61 break; 62 } 63 64 for (i=a;;i+=d) 65 { 66 if (vis[i]==true) 67 { 68 cnt++; 69 } 70 71 if (cnt==n)//找到第n個素數 72 { 73 printf("%d\n",i); 74 break; 75 } 76 } 77 } 78 79 80 return 0; 81 }

POJ3006-Dirichlet's Theorem on Arithmetic Progressions