UVA 10140

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;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值