• ZJNU 1223


    因为最大可以达到int极限

    明显直接筛选不可能完成

    所以从其因子入手

    因为任何不是素数的数都有除了1与其自身之外的因子

    因此,我们筛出2^(31/2)≈46350之内的所有素数,以其作为因子再将题目给定区间内的所有不是素数的数标记排除

    然后将素数存放在prnum这个vector集合中便于调用

    在排除阶段,可以用

    l=((L+prnum[i]-1)/prnum[i])*prnum[i]

    计算出区间内的第一个是prnum[i]的倍数的数

    注意,如果计算出来的使其本身,取倍数

    再用

    r=R/prnum[i]*prnum[i]

    计算出最后一个是prnum[i]的倍数的数

    符合条件时,从l到r,每次加prnum[i],标记出所有以prnum[i]为因子的数

    因为无法直接开数组标记到大数

    但又因为R-L≤1000000

    所以可以对位置进行转换

    标记时取-L+1,取出时取-1+L

    最后将区间内的素数取出放在ans这个vector集合内,对答案进行判断即可

    (注意特殊情况的判断)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    vector<ll> prnum,ans;
    bool prim[46400],ar[1000010];
    int main(){
        ll L,R,i,j,cnt,l,r,mxdis,mndis,mxn1,mxn2,mnn1,mnn2,d;
        scanf("%lld%lld",&L,&R);
        memset(prim,true,sizeof prim);
        prim[0]=prim[1]=false;
        for(i=2;i<=215;i++)
            if(prim[i])
                for(j=2*i;j<=46350;j+=i)
                    prim[j]=false;//埃氏筛法
        prnum.push_back(2);
        for(i=3;i<=46349;i+=2)
            if(prim[i])
                prnum.push_back(i);//将素数放置在prnum内
        cnt=prnum.size();
        memset(ar,true,sizeof ar);
        if(L==1)
            ar[1]=false;
        for(i=0;i<cnt;i++){
            l=((L+prnum[i]-1)/prnum[i])*prnum[i];
            if(l==prnum[i])//如果计算得出的l恰好为第i个素数本身,跳过它,取其倍数
                l+=l;
            if(l>R)
                continue;
            r=R/prnum[i]*prnum[i];
            for(j=l;j<=r;j+=prnum[i])
                ar[j-L+1]=false;//标记
        }
        for(i=1;i<=R-L+1;i++)
            if(ar[i])
                ans.push_back(i-1+L);//将指定区间内的所有素数提出
        cnt=ans.size();
        if(cnt<2)
            puts("There are no adjacent primes.");
        else{
            mndis=mxdis=ans[1]-ans[0];
            mxn1=mnn1=ans[0];
            mxn2=mnn2=ans[1];
            for(i=2;i<cnt;i++){
                d=ans[i]-ans[i-1];
                if(d>mxdis){
                    mxdis=d;
                    mxn1=ans[i-1];
                    mxn2=ans[i];
                }
                if(d<mndis){
                    mndis=d;
                    mnn1=ans[i-1];
                    mnn2=ans[i];
                }
            }
            printf("%lld,%lld are closest, %lld,%lld are most distant.
    ",mnn1,mnn2,mxn1,mxn2);
        }
        
        return 0;
    }
  • 相关阅读:
    [LeetCode] Min Stack
    [LeetCode] Find Minimum in Rotated Sorted Array
    [LeetCode] Maximum Product Subarray
    [Jobdu] 题目1504:把数组排成最小的数
    [Jobdu] 题目1544:数字序列区间最小值
    Python2.3-原理之语句和语法
    Python2.5-原理之模块
    Vim2.1-Vim简明教程【CoolShell】【非原创】
    Python2.6-原理之类和oop(下)
    QT1.1-与Opencv的hello world
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12233657.html
Copyright © 2020-2023  润新知