POJ2689 筛素数 xingxing在努力
此题就是让你筛选出[l, u]的素数,由于u最大是2^32次方, 所以我们只需要筛出[l, u]的合数即可求出素数。。u的最大质因数不超过2^16次方因此我们求出1-2^16的质数然后筛出l, u的合数即可。。(注意1既不是合数也不是质数),代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> using namespace std; const int maxn = 66000 + 10; typedef long long ll; int vis[maxn], primes[maxn], num; void GetPrime(int n) { memset(vis, 0, sizeof(vis)); int m = sqrt(n + 0.5); for(int i=2; i<=m; i++) if(!vis[i]) for(int j=i*i; j<=n; j+=i) vis[j] = 1; num = 0; for(int i=2; i<=n; i++) if(vis[i]==0) primes[num++] = i; } bool vs[1000000 + 10]; ll prime[1000000 + 10], nm; void shai(ll l, ll u) { if(l == 1) l++; memset(vs, 0, sizeof(vs)); ll m = sqrt(u+0.5); for(ll a=0; a<num; a++) { ll i = primes[a]; if(i > m) break; ll s; if(i >= l) s = 2*i; else //i<l { if(l%i==0) s=l; else s=(l/i+1)*i; } for(ll j=s; j<=u; j+=i) vs[j-l] = 1; } nm = 0; for(ll i=0; i<=u-l; i++) if(!vs[i]) prime[nm++] = i+l; } int main() { GetPrime(66000); int l, u; while(cin>>l>>u) { shai(l, u); if(nm == 0||nm==1) printf("There are no adjacent primes.\n"); else { ll cloa=0, clob=100000000, difa=1, difb=1; for(int i=1; i<nm; i++) { if(prime[i]-prime[i-1]<clob-cloa) cloa=prime[i-1], clob=prime[i]; if(prime[i]-prime[i-1]>difb-difa) difa=prime[i-1], difb=prime[i]; } printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n", cloa, clob, difa, difb); } } return 0; }

浙公网安备 33010602011771号