poj 2689 Prime Distance 二次筛法,找出给定区间所有约数

题目地址: http://poj.org/problem?id=2689

题目思路: 找出int 内所有素数空间上时不允许的,但是题目要求l ,u的差不超过100w ,在空间上还是允许的。

然后先找出5w以内的素数,这样的可以中这些素数作为合数最小的素因子将这个合数筛掉。    

  几个要注意的地方 【1】  因为l可能很大,j的起点不能去“p*p”  然后比L小就加一个p,想一下如果p=2,l很大会花很多时间的。 【2】  然后就是这个j 要用long long 存 ,因为我们找到的j的初值是p 的倍数中第一个大于等于L的,l很大时可能超long long。  【3】  这个筛法筛去的第一个数是4 所以1要特判  l==1 则 b[0]=1;

【4】 每次输入后要将b归零 【5】 将素数存在新的数组里面时,用数组会比用向量快得多,用向量就会超时。


代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;

#define N 50000

typedef long long   ll;
bool p[N+5];
int prime1[N];
ll prime2[1000000];
bool b[1000010];


int nprime1=0,nprime2=0;
void   pre()
{
   int len =sqrt(N);
   for(int i=2;i<=len;i++)
    if(p[i]==0)
     for(int j=i*i;j<=N;j+=i)
        p[j]=1;

    for(int i=2;i<=N;i++)
       if(p[i]==0)
      prime1[nprime1++]=i;



}



int main()
{

  pre();

 ll l,u;
 while(cin>>l>>u)
  {
    memset(b,0,sizeof(b));

    int cnt=0;
    for(int i=0;i<nprime1;i++)
  {
       ll j=l/prime1[i];
       while(j*prime1[i]<l||j<=1)  j++;

       for(j=j*prime1[i];j<=u;j+=prime1[i])
          {

           b[j-l]=1;
          }
  }


     if(l==1)  b[0]=1;

     for(int i=0;i<=u-l;i++)
       if(b[i]==0)
       {
         prime2[cnt++]=i+l;

       }


     if(cnt>=2)
     {
          int minv=10000000;
          int maxv=0;

          ll minr,minl,maxl,maxr;

          for(int i=0;i<cnt-1;i++)
           {
              if(prime2[i+1]-prime2[i]<minv)
              {
                  minl=prime2[i];
                  minr=prime2[i+1];
                  minv=minr-minl;
              }

              if(prime2[i+1]-prime2[i]>maxv)
              {
                  maxl=prime2[i];
                  maxr=prime2[i+1];
                  maxv=maxr-maxl;

              }
           }


          cout<<minl<<","<<minr<<" are closest, "<<maxl<<","<<maxr<<" are most distant."<<endl;
         // printf("%lld,%lld are closest, %lld,%lld are most distant.\n", minl, minr, maxl, maxr);
     }
     else
     cout<<"There are no adjacent primes."<<endl;
       //printf("There are no adjacent primes.\n");
  }

}




转载于:https://www.cnblogs.com/814jingqi/p/3310438.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值