[素数] POJ2689 Prime Distance
首先应该有一个常识,int的最大值在2e9左右......
而一般的OJ,可以认为O(n) 1e8以上就很难跑过了
但是,任何一个不超过2e9的n一定有一个不超过2e5的质因子,我们可以用筛法筛出[L,R]中的质数
注意数组不要越界
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 5e6 + 10;
int book[maxn], p[maxn];
int cnt = 0;
void init(int n) {
book[1] = 1;
for (int i = 2; i <= n; i++) {
if (!book[i]) p[++cnt] = i;
for (int j = 1; j <= cnt && i * p[j] <= n; j++) {
book[i * p[j]] = 1;
if (i % p[j]) break;
}
}
}
int notprime[maxn];
vector <int> prime;
int main() {
init(maxn);
int L, R;
//for (int i = 1; i <= 100; i++) printf("%d ", p[i]);
while (scanf("%d%d", &L, &R) == 2) {
memset(notprime, 0, sizeof(notprime));
prime.clear();
if (1 - L >= 0) notprime[1 - L] = 1;
for (int i = 1; i <= cnt && p[i] <= R / p[i]; i++) {
for (int j = L / p[i] < 2 ? 2 : L / p[i]; p[i] <= R / j; j++) {
if (p[i] * j - L >= 0) notprime[p[i] * j - L] = 1;
}
}
pair <int, int> ans1 = {0, 0}, ans2 = {0, 0};
int mind = maxn, maxd = -maxn;
for (int i = 0; i <= R - L; i++) {
if (!notprime[i]) prime.push_back(i + L);
}
//for (auto u : prime) printf("%d ", u);
//puts("");
if (prime.size() < 2) {
puts("There are no adjacent primes.");
continue;
}
for (int i = 1; i < prime.size(); i++) {
if (prime[i] - prime[i - 1] < mind) {
mind = prime[i] - prime[i - 1];
ans1 = {prime[i - 1], prime[i]};
}
if (prime[i] - prime[i - 1] > maxd) {
maxd = prime[i] - prime[i - 1];
ans2 = {prime[i - 1], prime[i]};
}
}
printf("%d,%d are closest, %d,%d are most distant.\n", ans1.first, ans1.second, ans2.first, ans2.second);
}
return 0;
}