2017ecjtu-summer training #7 POJ 2689
阿新 • • 發佈:2017-08-02
ble ac代碼 pre mat itself not sin pri stream Prime Distance
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
Each line of input will contain two positive integers, L and U, with L < U. The difference between L and U will not exceed 1,000,000.
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 18731 | Accepted: 5006 |
Description
The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper factors (it is only evenly divisible by 1 and itself). The first prime numbers are 2,3,5,7 but they quickly become less frequent. One of the interesting questions is how dense they are in various ranges. Adjacent primes are two numbers that are both primes, but there are no other prime numbers between the adjacent primes. For example, 2,3 are the only adjacent primes that are also adjacent numbers.Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
Input
Output
For each L and U, the output will either be the statement that there are no adjacent primes (because there are less than two primes between the two given numbers) or a line giving the two pairs of adjacent primes.Sample Input
2 17 14 17
Sample Output
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
題意:輸入區間[l,u],其中l和u為int範圍的整數,區間最大為1000000。求出[l,u]中,相鄰素數只差最大和最小的素數對。當存在多個時,輸出較小的素數對。
題解:l,u範圍太大,不能直接求int範圍的素數。而區間間隔比較小,只有1e6,而且對於int範圍內的合數來說,最小質因子必定小於2^16。所以可以求出[l,u]中合數,轉而求出素數,然後暴力枚舉所有素數對即可。
如何求區間[l,u]中的合數:上面已經說了,合數的最小質因子小於2^16,即小於50000。所以先求出小於50000的所有素數。則區間[l,u]中的合數,必定可以表示為小於50000的素數的倍數。對於素數p來說,令a=(l-1)/p+1,b=u/p。則枚舉j=a到b,j*p可以枚舉所有[l,u]中質因子含有p的合數。枚舉所有小於50000的素數,然後用上述方式枚舉倍數,即可找出[l,u]中所有的合數。
由於l,u在int範圍,所以不能直接用數組標記。需要加個偏移量,取l,則數組大小小於1e6的f[0,u-l],即可標記。
接著枚舉區間中所有的相鄰素數對即可。
特別註意:由於1不是小於50000的素數的倍數,所以在與合數相斥中,會被當成素數。需要特別處理下。
AC代碼
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream> 7 #include <queue> 8 #include <vector> 9 #include <algorithm> 10 #define maxn 50010 11 #define maxm 1000010 12 #define inf 0x3f3f3f3f 13 using namespace std; 14 typedef long long ll; 15 int vis[maxm],f[maxm]; 16 int prime[maxn],prime1[maxm]; 17 int mind,maxd,minl,minr,maxl,maxr; 18 int t,t1; 19 ll L,R; 20 void init() //篩選出50000以內的素數 21 { 22 t=0; 23 memset(vis,0,sizeof(vis)); 24 for(int i=2;i<maxn;i++) 25 { 26 if(!vis[i]) 27 { 28 prime[t++]=i; 29 for(int j=i+i;j<maxn;j+=i) 30 vis[j]=1; 31 } 32 } 33 } 34 void selet() 35 { 36 memset(vis,0,sizeof(vis)); //*特別考慮1 37 for(int i=0;i<t;i++) //標記int範圍內的合數 38 { 39 ll b=L/prime[i]; 40 while(b*prime[i]<L||b<=1) 41 b++; 42 for(ll j=b*prime[i];j<=R;j+=prime[i]) 43 vis[j-L]=1; //節約空間,降低空間復雜度 44 } 45 if(L==1) 46 vis[0]=1; 47 t1=0; 48 for(ll i=L;i<=R;i++) //找出區間內的素數存進數組 49 { 50 if(!vis[i-L]) 51 prime1[t1++]=i; 52 } 53 } 54 void solve() 55 { 56 selet(); 57 mind=inf,maxd=-inf; 58 minl=minr=maxl=maxr=-1; 59 for(int i=1;i<t1;i++) //枚舉區間內的素數,更新要輸出的值 60 { 61 int d=prime1[i]-prime1[i-1]; 62 if(d<mind) 63 { 64 mind=d; 65 minl=prime1[i-1]; 66 minr=prime1[i]; 67 } 68 if(d>maxd) 69 { 70 maxd=d; 71 maxl=prime1[i-1]; 72 maxr=prime1[i]; 73 } 74 } 75 } 76 int main(int argc, char const *argv[]) 77 { 78 init(); 79 while(cin>>L>>R) 80 { 81 solve(); 82 if(t1<2) 83 printf("There are no adjacent primes.\n"); 84 else 85 printf("%d,%d are closest, %d,%d are most distant.\n",minl,minr,maxl,maxr); 86 } 87 return 0; 88 }
2017ecjtu-summer training #7 POJ 2689