题意:给出一个区间L R 区间内的距离最远和最近的2个素数 并且是相邻的 R-L <= 1000000 但是L和R会很大
思路:一般素数筛选法是拿一个素数 然后它的2倍3倍4倍...都不是 然后这题可以直接从2的L/2倍开始它的L/2+1倍L/2+2倍...都不是素数
首先筛选出一些素数 然后在以这些素数为基础 在L-R上在筛一次因为 R-L <= 1000000 可以左移开一个1百万的数组
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn = 1000010; typedef __int64 LL; int vis[maxn]; int p[maxn]; int prime[maxn]; //筛素数 void sieve(int n) { int m = sqrt(n+0.5); memset(vis, 0, sizeof(vis)); vis[0] = vis[1] = 1; for(int i = 2; i <= m; i++) if(!vis[i]) for(int j = i*i; j <= n; j += i) vis[j] = 1; } int get_primes(int n) { sieve(n); int c = 0; for(int i = 2; i <= n; i++) if(!vis[i]) prime[c++] = i; return c; } int main() { LL L, R; int c = get_primes(100000); while(scanf("%I64d %I64d", &L, &R) != EOF) { if(L <= 2) L = 2; memset(p, 0, sizeof(p)); for(int i = 0; i < c; i++) { if(prime[i] > R) break; LL t = L / prime[i]; if(t <= 1) t = 2; LL j = t*prime[i]; while(j < L) j += prime[i]; for(; j <= R; j += prime[i]) { //printf("%d,,", j); p[j-L] = 1; } } LL ans1 = 999999999, ans2 = 0; LL x1, y1, x2, y2, x = -1, y = -1; for(LL i = L; i <= R; i++) { if(!p[i-L]) { //printf("%d\n", i); x = y; y = i; if(x != -1 && y != -1) { if(ans1 > y-x) { ans1 = y-x; x1 = x; y1 = y; } if(ans2 < y-x) { ans2 = y-x; x2 = x; y2 = y; } } } } if(x == -1 || y == -1) { puts("There are no adjacent primes."); continue; } printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n", x1, y1, x2, y2); } return 0; }
POJ 2689 Prime Distance 素数筛选法应用,布布扣,bubuko.com
时间: 2024-10-15 06:21:47