标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 13961 | Accepted: 3725 |
Description
Input
Output
Sample Input
2 17 14 17
Sample Output
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
题目大意:给一个区间,找出这个区间内相邻的两个素数中差最大和最小的两个。
题目解析:两种方法,一种是 枚举 + Miller_Rabbin快速判定素数,另一种是将标记数组区间平移,两次筛素数。
第一种方法:
1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 # include<cstdlib> 5 # include<algorithm> 6 using namespace std; 7 # define ll long long 8 unsigned mypow(unsigned a,unsigned b,unsigned m) 9 { 10 if(b==0) 11 return 1; 12 if(b==1) 13 return a%m; 14 ll temp=mypow(a,b/2,m); 15 temp*=temp; 16 temp%=m; 17 if(b&1) 18 temp*=a; 19 temp%=m; 20 return temp; 21 } 22 bool Miller_Rabbin(unsigned x) 23 { 24 if(x==2) 25 return true; 26 for(int i=1;i<=2;++i){ 27 unsigned a=rand()%(x-2)+2; 28 if(mypow(a,x-1,x)!=1) 29 return false; 30 } 31 return true; 32 } 33 int main() 34 { 35 unsigned a,b; 36 unsigned l1,l2,r1,r2,t; 37 int minn,maxn; 38 while(scanf("%u%u",&a,&b)!=EOF) 39 { 40 if(a==1) 41 a=2; 42 minn=1000005; 43 maxn=0; 44 l1=l2=r1=r2=a; 45 bool yy=true; 46 for(int i=a;i<=b;++i){ 47 if(Miller_Rabbin(i)){ 48 if(yy){ 49 t=l1=r1=a; 50 yy=false; 51 } 52 else{ 53 if(minn>i-t){ 54 minn=i-t; 55 l1=t; 56 l2=i; 57 } 58 if(maxn<i-t){ 59 maxn=i-t; 60 r1=t; 61 r2=i; 62 } 63 } 64 t=i; 65 } 66 } 67 if(maxn==0){ 68 printf("There are no adjacent primes.\n"); 69 }else 70 printf("%u,%u are closest, %u,%u are most distant.\n",l1,l2,r1,r2); 71 } 72 return 0; 73 }
这种暴力的方法效率不高,在UVa上取30个随机数能AC,在ZOJ上取20个随机数能AC,但在POJ上无论如何都AC不了。原因就是这三个OJ对时间的要求分别是3s,2s,1s。
下面是两重筛的实现。标记数组用的很灵活。
1 # include<iostream> 2 # include<cstdio> 3 # include<cmath> 4 # include<map> 5 # include<vector> 6 # include<cstring> 7 # include<algorithm> 8 using namespace std; 9 const int N=46340; 10 int pri[N],mark[1000010],cnt; 11 vector<unsigned>v; 12 void init() 13 { 14 cnt=0; 15 fill(mark,mark+N+5,1); 16 for(int i=2;i<=N;++i){ 17 if(mark[i]) 18 pri[cnt++]=i; 19 for(int j=0;j<cnt&&i*pri[j]<=N;++j){ 20 mark[i*pri[j]]=0; 21 if(i%pri[j]==0) 22 break; 23 } 24 } 25 } 26 void work(unsigned a,unsigned b) 27 { 28 v.clear(); 29 if(a==1) 30 ++a; 31 memset(mark,0,sizeof(mark)); 32 for(int i=0;i<cnt;++i){ 33 if(pri[i]>b) 34 break; 35 for(int c=a/pri[i];c*pri[i]<=b;++c){ 36 if(c<=1) 37 continue; 38 if(c*pri[i]<a) 39 continue; 40 mark[c*pri[i]-a]=1; 41 } 42 } 43 for(int i=0;i<=b-a;++i){ 44 if(mark[i]==0) 45 v.push_back(i+a); 46 } 47 } 48 void solve() 49 { 50 int l=v.size(); 51 if(l<2){ 52 printf("There are no adjacent primes.\n"); 53 return ; 54 } 55 int minn=1<<30,maxn=0; 56 unsigned l1,l2,r1,r2; 57 for(int i=1;i<l;++i){ 58 if(minn>v[i]-v[i-1]){ 59 minn=v[i]-v[i-1]; 60 l1=v[i-1]; 61 l2=v[i]; 62 } 63 if(maxn<v[i]-v[i-1]){ 64 maxn=v[i]-v[i-1]; 65 r1=v[i-1]; 66 r2=v[i]; 67 } 68 } 69 printf("%u,%u are closest, %u,%u are most distant.\n",l1,l2,r1,r2); 70 } 71 int main() 72 { 73 init(); 74 unsigned a,b; 75 while(scanf("%u%u",&a,&b)!=EOF) 76 { 77 work(a,b); 78 solve(); 79 } 80 return 0; 81 }
POJ-2689 Prime Distance (两重筛素数,区间平移)
标签:
原文地址:http://www.cnblogs.com/20143605--pcx/p/4701034.html