NBUT 1454 Lux (求区间内的素数并求差值)

  • [1454] Lux

  • 时间限制: 2000 ms 内存限制: 65535 K
  • 问题描述
  • Lux pretty good at the math. And she is thinking about the prime question.

     

    Lux want to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum) and the two are most distance (i.e. C2-C1 is the maximun).

     

    If there are other pairs that are the same distance apart, use the first pair.

  • 输入
  • There are muti-case.
    For each test case, contains two integers L and U (1 ≤ L < U ≤ 2, 147, 483, 647).
    (U - L < 1,000,000)
  • 输出
  • For each test case output the two closest adjacent primes and the two most distant adjacent primes.
    If there are no adjacent primes print "-1";
  • 样例输入
  • 2 17
    14 17
  • 样例输出
  • 2 3 7 11
    -1
  • 提示
  • 来源
  • Monkeyde17

题意:分别求区间内两个差最小的两个素数和差最大的素数

分析:打出素数表,然后暴力求求出最大值和最小值

#pragma comprint(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#define LL __int64
#define FIN freopen("in.txt","r",stdin)
using namespace std;
const int MAXN=1000000+5;
const int INF=0x3f3f3f3f;
int vis[MAXN],pri[MAXN];
int tot;
void sieve(int n)
{
    int m=(int)sqrt(n+0.5);
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=m;i++) if(!vis[i])
        for(int j=i*i;j<=n;j+=i) vis[j]=1;
}
void gen_primes(int n)
{
    sieve(n);
    tot=0;
    for(int i=2;i<=n;i++) if(!vis[i])
        pri[tot++]=i;
}                                         //筛法求素数
int subpri[MAXN];
bool sign[MAXN];
int getsubprimes(LL a,LL b)
{
    LL totl=0,i,j;
    memset(sign,true,sizeof(sign));
    if(a<2) a=2;
    LL l=b-a+1;
    for(i=0;i<tot;i++)
    {
        if((j=pri[i]*(a/pri[i]))<a) j+=pri[i];
        if(j<pri[i]*pri[i]) j=pri[i]*pri[i];
        for(;j<=b;j+=pri[i]) sign[j-a]=false;
    }
    for(int i=0;i<l;i++)
        if(sign[i]) subpri[totl++]=a+i;
    return totl;
}                                         //求区间素数
int main()
{
    //FIN;
    gen_primes(100000);
    int L,R;
    while(scanf("%d %d",&L,&R)!=EOF)
    {
        int cnt=getsubprimes(L,R);
        int x,y,xx,yy;
        if(cnt<2) {printf("-1\n");}
        else
        {
            int maxn=-INF,minn=INF,numa,numb;
            for(int i=0;i<cnt-1;i++)
            {
                int numa=subpri[i],numb=subpri[i+1];
                if(numb-numa>maxn)
                {
                    maxn=numb-numa;
                    x=i;
                    y=i+1;
                }
                if(numb-numa<minn)
                {
                    minn=numb-numa;
                    xx=i;
                    yy=i+1;
                }
            }
            printf("%d %d %d %d\n",subpri[xx],subpri[yy],subpri[x],subpri[y]);
        }
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/clliff/p/4751243.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值