POJ3006-Dirichlet's Theorem on Arithmetic Progressions

题意:

设一个等差数列,首元素为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 }

 

posted @ 2018-05-26 15:59  hemeiwolong  阅读(170)  评论(0编辑  收藏  举报