素数相关
Posted 不可爱的小可爱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了素数相关相关的知识,希望对你有一定的参考价值。
1-n之间有多少个素数
10的1次方 4
10的2次方 25
10的3次方 168
10的4次方 1229
10的5次方 9592
10的6次方 78498
10的7次方 664579
10的8次方 5761455
10的9次方 50847534
1、单独判断一个数是否为素数
1 bool prime(int n) 2 { 3 if(n==0||n==1) return false; 4 if(n==2) return true; 5 for(int i=2;i<=sqrt(n);i++) 6 if(n%i==0) 7 return false; 8 return true; 9 }
2、筛法筛素数 ,求小于maxn的素数
isprime[ ] 保存小于maxn的数是否为素数,false表示不是素数,true表示素数
prime[ ] 保存小于maxn的素数有哪些,从0开始,长度为len
1 const int maxn=100; 2 bool isprime[maxn]; 3 int prime[maxn]; 4 int len=0; 5 6 void sieve(int n) 7 { 8 for(int i=0;i<n;i++) 9 isprime[i]=1; 10 isprime[0]=isprime[1]=0; 11 for(int i=2;i<n;i++) 12 if(isprime[i]) 13 { 14 prime[len++]=i; 15 for(int j=2*i;j<n;j+=i) 16 isprime[j]=0; 17 } 18 } 19 //主函数调用sieve(maxn)
3、如果只要求小于maxn的素数有哪些,去掉isprime[ ]数组
下面模板中 prime[ ] 中保存的是maxn中的素数有哪些,标号从1开始,总的素数个数为prime[0] ,它包含的素数范围为 prime[1]到prime[ prime[0] ]
1 const int maxn=100; 2 int prime[maxn+1]; 3 4 void getPrime() 5 { 6 memset(prime,0,sizeof(prime));//一开始prime都设为0代表都是素数(反向思考) 7 for(int i=2;i<=maxn;i++) 8 { 9 if(!prime[i]) 10 prime[++prime[0]]=i; 11 for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++) 12 { 13 prime[prime[j]*i]=1;//prime[k]=1;k不是素数 14 if(i%prime[j]==0) 15 break; 16 } 17 } 18 }
4、大区间筛素数
POJ:2689
给出一个区间[L,R], 范围为1<=L< R<=2147483647,区间长度长度不超过1000000
求距离最近和最远的两个素数(也就是相邻的差最小和最大的素数)
筛两次,第一次筛出1到1000000的素数,因为1000000^2已经超出int范围,这样的素数足够了。
函数getPrim(); prime[ ] 存第一次筛出的素数,总个数为prime[0]
第二次利用已经筛出的素数去筛L,R之间的素数
函数getPrime2(); isprime[] 判断该数是否为素数 prime2[ ]筛出的素数有哪些,一共有prime2[0]个
模板:
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn=1e6; 9 int prime[maxn+10]; 10 11 void getPrime() 12 { 13 memset(prime,0,sizeof(prime));//一开始prime都设为0代表都是素数(反向思考) 14 for(int i=2;i<=maxn;i++) 15 { 16 if(!prime[i]) 17 prime[++prime[0]]=i; 18 for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++) 19 { 20 prime[prime[j]*i]=1;//prime[k]=1;k不是素数 21 if(i%prime[j]==0) 22 break; 23 } 24 } 25 } 26 27 bool isprime[maxn+10]; 28 int prime2[maxn+10]; 29 30 void getPrime2(int L,int R) 31 { 32 memset(isprime,1,sizeof(isprime)); 33 //isprime[0]=isprime[1]=0;//这句话不能加,考虑到左区间为2的时候,加上这一句,素数2,3会被判成合数 34 if(L<2) L=2; 35 for(int i=1;i<=prime[0]&&(long long)prime[i]*prime[i]<=R;i++) 36 { 37 int s=L/prime[i]+(L%prime[i]>0);//计算第一个比L大且能被prime[i]整除的数是prime[i]的几倍,从此处开始筛 38 if(s==1)//很特殊,如果从1开始筛的话,那么2会被筛成非素数 39 s=2; 40 for(int j=s;(long long)j*prime[i]<=R;j++) 41 if((long long)j*prime[i]>=L) 42 isprime[j*prime[i]-L]=false; //区间映射 ,比如区间长度为4的区间[4,7],映射到[0,3]中,因为题目范围2,147,483,647数组开不出来 43 } 44 prime2[0]=0; 45 for(int i=0;i<=R-L;i++) 46 if(isprime[i]) 47 prime2[++prime2[0]]=i+L; 48 } 49 50 int main() 51 { 52 getPrime(); 53 int L,R; 54 while(scanf("%d%d",&L,&R)!=EOF) 55 { 56 getPrime2(L,R); 57 if(prime2[0]<2) 58 printf("There are no adjacent primes.\n"); 59 else 60 { 61 //for(int i=1;i<=prime2[0];i++) 62 // cout<<prime2[i]<<endl; 63 int x1=0,x2=1000000,y1=0,y2=0; 64 for(int i=1;i<prime2[0];i++) 65 { 66 if(prime2[i+1]-prime2[i]<x2-x1) 67 { 68 x1=prime2[i]; 69 x2=prime2[i+1]; 70 } 71 if(prime2[i+1]-prime2[i]>y2-y1) 72 { 73 y1=prime2[i]; 74 y2=prime2[i+1]; 75 } 76 } 77 printf("%d,%d are closest, %d,%d are most distant.\n",x1,x2,y1,y2); 78 } 79 } 80 return 0; 81 }
以上是关于素数相关的主要内容,如果未能解决你的问题,请参考以下文章