poj 2689 Prime Distance (区间素数筛法)

大体题意:给你两个数l,u同时l,u在int以内(会很大),但是区间长度不会超过1e6;让你找到在这个区间内相邻素数距离最大与最小

第一想法就是暴力l,u所有素数但是l,u都太大数组筛法的话筛不到。

处理方法:就是先找到sqrt(u)以内的素数,然后就可以按这个区间内的素数找到对称区间内的合数(即[sqrt(u),u]内的合数)其余的就是素数了。然后你就只需要用另一个数组标记[l,u] (偏移l后的)内的素数。然后暴力就可以了

#include<iostream>
#include<string.h>
#define ll long long
using namespace std;
const int N=5e4+5;
const int M=1e6+5;
int prime[N],s[N],d[M];
int cnt=0;
void isprime()
{
    s[1]=1;
    for(int i=2;i<=N;i++)
    {
        if(s[i]==0)
            prime[cnt++]=i;
        for(int j=0;j<cnt,i*prime[j]<=N;j++)
        {
            s[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
    ll l,u;
    isprime();
    while(cin>>l>>u)
    {
        if(l==1) l=2;///1不是素数特判一下
        memset(d,0,sizeof(d));///每次清空
        for(int i=0;i<cnt;i++)
        {
            ///prime[i]*a<=l
            ///prime[i]*b>=u
            int a=(l-1)/prime[i];
            int b=u/prime[i];
            for(int j=a;j<=b;j++)
            {
                if(j>1)
                    d[prime[i]*j-l]=1;///l---u中第几个是合数
            }
        }
        int minn=M,maxn=-1,x1=0,x2=0,y1=0,y2=0,p=-1;
        for(int i=0;i<=u-l;i++)
        {
            //cout<<d[i]<<endl;
            if(d[i]==0)
            {
                if(p==-1) {p=i;continue;}///记录第一个素数
                if(i-p<minn) {minn=i-p;x1=p+l;y1=i+l;}
                if(i-p>maxn) {maxn=i-p;x2=p+l;y2=i+l;}
                p=i;
            }
        }
        if(maxn==-1)cout<<"There are no adjacent primes."<<endl;
        else cout<<x1<<","<<y1<<" are closest, "<<x2<<","<<y2<<" are most distant."<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值