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.
Source
题意:输出区间[l, r]中,差最大和最小的两对素数。
思路:因为范围很大,区间相对较小,所以我们先筛选出2^16范围内的素数,然后通过小的区间去删除大区间的合数(每个合数都能通过素数相乘得到)。最后遍历
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> typedef long long ll; using namespace std; const int INF = 1<<30; const int inf = 60000; const int maxn = 1000005; int prime[maxn], vis[maxn], cnt; void init() { cnt = 0; for (ll i = 2; i < inf; i++) if (!vis[i]) { prime[cnt++] = i; for (ll j = i*i; j < inf; j += i) vis[j] = 1; } } int isprime[maxn], a[maxn], c; int main() { int l, r; init(); while (scanf("%d%d", &l, &r) != EOF) { memset(isprime, 1, sizeof(isprime)); if (l == 1) l = 2; for (int i = 0; i < cnt && (ll)prime[i]*prime[i] <= r; i++) { int s = l / prime[i] + (l % prime[i] > 0); if (s == 1) s = 2; for (int j = s; (ll)j*prime[i] <= r; j++) if ((ll)j*prime[i] >= l) isprime[j*prime[i]-l] = 0; } c = 0; for (int i = 0; i <= r-l; i++) if (isprime[i]) a[c++] = i + l; if (c < 2) { printf("There are no adjacent primes.\n"); continue; } else { int x1 = 0, x2 = 0, y1 = 0, y2 = INF; for (int i = 1; i < c; i++) { if (a[i] - a[i-1] > x2 - x1) { x1 = a[i-1]; x2 = a[i]; } if (a[i] - a[i-1] < y2 - y1) { y1 = a[i-1]; y2 = a[i]; } } printf("%d,%d are closest, %d,%d are most distant.\n", y1, y2, x1, x2); } } return 0; }