POJ3006-Dirichlet's Theorem on Arithmetic Progressions
Posted hemeiwolong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于POJ3006-Dirichlet's Theorem on Arithmetic Progressions的主要内容,如果未能解决你的问题,请参考以下文章
Jessica's Reading Problem POJ 3320(尺取)
poj 3128 Leonardo's Notebook (置换群的整幂运算)