meaning of the problem:
Given two int L and U, find 2 pair of prime number. The first pair should be adjacent prime number the difference between whom is the smallest and that of the other pair should be the largest.
Outline:
Since the range for U and L is 1~(2^32-1), difference between U and L will not exceed 1,000,000, we can easily get prime number in 2^16 using sieve method. And then use the prime numbers we got to kick out non prime number in U and L,
Tips: the function cal is important so that we will not get TLE.
if you get run time error, you can check whether you used s- u in the flag_in_range.
#include<stdlib.h>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<algorithm>
#include <cstdio>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define maxfacprime 65536 // int^1/2
using namespace std;
int prime[50000];
bool flag[70000];
int count_p = 0;
void findprime()
{
int i, j;
memset(flag, true, sizeof(flag));
for (i = 2; i <= maxfacprime; i++)
{
if (flag[i] == true) prime[++count_p] = i;
for (j = 1; j <= count_p&&i*prime[j] <= maxfacprime; j++)
{
flag[i*prime[j]] = false;
if (i%prime[j] == 0)
break;
}
}
}
long long int prime_in_range[1000000];
bool flag_in_range[1000000];
long long int cal(long long int n,long long int lim)
{
long long int k = lim / n;
if (k*n == lim)
return lim;
else return n*(k + 1);
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
//cout << maxfacprime;
long long int u, v;
findprime();
while (cin >> u >> v)
{
if (u == v)
{
printf("There are no adjacent primes.\n");
continue;
}
int count_prime_in_range = 0;
memset(flag_in_range, false, sizeof(flag_in_range));
long long int m = (int)sqrt(v) + 1;
for (int i = 1; i <= count_p; i++)
{
if (prime[i] > m)
break;
// long long int j = 2;
/* while (j*prime[i] < u)
j++;*/
for (long long int s = cal(prime[i],u); s <= v; s += prime[i])
{
if (s == prime[i])
continue;
flag_in_range[s-u] = true;
}
}
for (long long int k = u; k <= v; k++)
{
if (k == 1)
continue;
if (flag_in_range[k-u])
continue;
prime_in_range[count_prime_in_range++] = k;
}
long long int small_dis = 1000000;
long long int large_dis = 0;
long long int s1, s2;
long long int l1, l2;
for (int i = 0; i < count_prime_in_range - 1; i++)
{
long long int dis = prime_in_range[i + 1] - prime_in_range[i];
if (small_dis > dis)
{
small_dis = dis;
s1 = prime_in_range[i];
s2 = prime_in_range[i+1];
}
if (large_dis < dis)
{
large_dis = dis;
l1 = prime_in_range[i];
l2 = prime_in_range[i + 1];
}
}
if (count_prime_in_range <= 1)
printf("There are no adjacent primes.\n");
else printf("%lld,%lld are closest, %lld,%lld are most distant.\n", s1, s2, l1, l2);
}
return 0;
}