zoukankan      html  css  js  c++  java
  • AcWing 196. 质数距离(筛法+离散化)打卡

    给定两个整数L和U,你需要在闭区间[L,U]内找到距离最接近的两个相邻质数C1和C2(即C2-C1是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。

    同时,你还需要找到距离最远的两个相邻质数D1和D2(即D1-D2是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。

    输入格式

    每行输入两个整数L和U,其中L和U的差值不会超过1000000。

    输出格式

    对于每个L和U ,输出一个结果,结果占一行。

    结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)

    如果L和U之间不存在质数对,则输出“There are no adjacent primes.”。

    数据范围

    1L<U23111≤L<U≤231−1

    输入样例:

    2 17
    14 17
    

    输出样例:

    2,3 are closest, 7,11 are most distant.
    There are no adjacent primes.


    题意:找到给定范围内相邻质数最大和最小的质数对
    思路:给定的l,r的范围都达到了1e9,我们直接筛法存不了这么大,但是他的r-l<=1e6,这个时候我们就应该有数学上的抓关键词分析的想法,从这下手
    我们可以知道,每个合数肯定是由一个不大于sqrt(n)的素数和一个数的乘积化来的,那么我们就可以求出1-sqrt(r)的素数然后枚举素数再用筛法分别乘以一个数
    达到的数说明就是一个合数,没有被乘到标记的说明就是素数


    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=1e5+1000,M=1e6+10;
    ll prime[N],a[N];
    int p[M];
    int zs(int n)//判定质数
    {
        memset(prime,0,sizeof(prime));
        memset(a,0,sizeof(a));
        for(int i=2;i<=n;i++)
        {
            if (!prime[i])
                a[++a[0]]=i;
            for(int j=i;j<=n/i;j++)
                prime[i*j]=1;
        }
    }
    int main()
    {
        int l,r;
        while(cin>>l>>r)
        {
            zs(sqrt(r));
            memset(p,0,sizeof(p));
            if (l==1)//1要特判啊
                p[0]=1;
            for(int i=1;i<=a[0];i++)
            {
                for(int j=ceil(l/a[i]);j<=floor(r/a[i]);j++)//celi为向上取整,floor为向下取整.
                    if (j!=1)
                        p[a[i]*j-l]=1;//统一减去l
            }
            int as=0,max_ans=0,min_ans=1e9;
            pair<int,int> ans_a,ans_b;
            for(int i=l;i<=r;i++)
                if (!p[i-l])
                {
                    if (as)
                    {
                        if (max_ans<i-as)
                        {
                            ans_a.first=as;
                            ans_a.second=i;
                            max_ans=i-as;
                        }
                        if (min_ans>i-as)
                        {
                            ans_b.first=as;
                            ans_b.second=i;
                            min_ans=i-as;
                        }
                    }
                    as=i;
                }
            if (max_ans==0 && min_ans==1e9)
                printf("There are no adjacent primes.
    ");//没有素数
            else
                printf("%d,%d are closest, %d,%d are most distant.
    ",ans_b.first,ans_b.second,ans_a.first,ans_a.second);
        }
    }
     
  • 相关阅读:
    科学美国人(Scientific American)部分段落小译
    Matlab安装使用libsvm
    【转】Matlab中特殊符号的写法
    计算机视觉资源
    AdaBoost
    AdaBoost人脸检测原理
    NLP常用开源/免费工具(转)
    搜索背后的奥秘——浅谈语义主题计算
    求数组当中子数组最大和
    求二叉树中两个节点的最低父节点
  • 原文地址:https://www.cnblogs.com/Lis-/p/10994809.html
Copyright © 2011-2022 走看看