• 素数区间筛法


    题目链接:https://cn.vjudge.net/contest/319720#overview

    题目大意:输入两个数L和U(1<=L<U<=2 147 483 647),要找出两个相邻素数C1和C2(L<=C1<C2<=U)是距离最小的,如果相邻素数不止一对,选择最初的,还要找出两个相邻的素数D1,和D2是距离最大的(同样在有多对的情况下选择最初的)

    其中L<U,L和U的差不超过1 000 000

    输入样例:

    2 17
    14 17

    输出样例:

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

    思路:

    需要求出给定范围内区间所有的素数,然后再把素数间的最大距离、最小距离求出来。所以我们首先得用筛法筛出区间[L,U]范围内的素数。

    因为数据区间超过的上界打到21亿,不能将所有小于21亿的素数存下来,不过我们发现区间的长度不超过1 000 000,使用筛法筛掉[L,U]区间的所有非素数,需要知道[L,U]区间的所有非素数的素数因子(因为一个非素数是被它最小的素因子筛掉)。2147483647内的数或者是素数,能被根号2147483647内的素数整除,也就是说,[L,U]区间的所有非素数的素数因子都在根号2147483647内。

    可以预先将根号2147483647内的所有素数找出来,然后用这些素数去筛掉指定区间的所有非素数

     1 #include<iostream>
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn=50005;
     9 int prime[maxn];
    10 int l,u,tot=0;
    11 bool isprime[1000005];
    12 void getprime(int N){
    13     memset(prime,0,sizeof(prime));
    14     for(int i=2;i<=N;i++){
    15         if(!prime[i])
    16             prime[tot++]=i;
    17         for(int j=0;j<tot&&prime[j]*i<=N;j++){
    18             prime[i*prime[j]]=1;
    19             if(i%prime[j]==0) break;
    20         }
    21     }
    22 }
    23 int main(){
    24     //freopen("../in.txt","r",stdin);
    25     getprime(50002);
    26     while(cin>>l>>u){
    27         memset(isprime,true,sizeof(isprime));
    28         for(int i=0;i<tot;i++){
    29             int a=(l-1)/prime[i]+1,b=u/prime[i]; // l和r表示了当前范围里的数对这个素数的最小倍数和最大倍数。 为什么这样写,可以自己举例来理解
    30             for(int j=a;j<=b;j++) if (j>1) isprime[j*prime[i]-l]=0; // 当j=1 的时候这个时候就是prime[i],prime[i]就是素数
    31         }
    32         if(l==1) isprime[0]=0; //注意特判l=1的情况
    33         int pos=-1,l1,r1,l2,r2,maxdis=0,mindis=0x3f3f3f3f;
    34         for(int i=0;i<=u-l;i++){
    35             if(isprime[i]){
    36                 if(pos==-1) {
    37                     pos=i;
    38                     continue;
    39                 }
    40                 if(i-pos<mindis){
    41                     l1=l+pos;
    42                     r1=l+i;
    43                     mindis=i-pos;
    44                 }
    45                 if(i-pos>maxdis){
    46                     maxdis=i-pos;
    47                     l2=l+pos;
    48                     r2=l+i;
    49                 }
    50                 pos=i;
    51             }
    52         }
    53         if(maxdis==0) printf("There are no adjacent primes.
    ");
    54         else printf("%d,%d are closest, %d,%d are most distant.
    ",l1,r1,l2,r2);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    hdu3829(最大独立集)
    hdu2444(判二分图+最大匹配)
    hdu2063+hdu1083(最大匹配数)
    hdu3622(二分+two-sat)
    poj3678(two-sat)
    hdu1824(two-sat)
    hdu3062(two-sat)
    POJ1067 取石子游戏
    POJ1066 Treasure Hunt
    POJ1065 Wooden Sticks
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11348370.html
Copyright © 2020-2023  润新知