poj 2689

        这是一道关于素数的题目,不过这是运用筛法求素数的方法求解区间内的素数,是一道很好的题目,会让你对筛法求素数有更好的理解(提示:下面的讲解都建立在懂得一般筛法求素数的基础上,所以如果不会,请先学习筛法求素数的算法)。

        这题要求相邻素数的最大和最小距离,但只要知道区间的所有的素数,这就很好解决了,所以解题重点在于筛法求一段区间的素数。一般筛法求素数是从2开始的一个区间,但这题左边的区间L可能离2很远,,且U很大,所以不能直接求[2,U]内的全部素数。但我们知道如果想筛2500内的素数,我们只要求出50内的素数,再筛去其余部分的非素数。同样,这里U最大2147483647,如果想筛出[2,2147483647]内的所有素数,那么只要有50000内的素数就可以了(当然2147483647开根号比50000小,我只是凑整到50000),这是筛法求素数能承受的大小,求出50000内的所有素数,那么[2,2147483647]中任意区间的素数同样可以用50000内的素数可以筛出来了。

        不过还要注意一个细节,筛法筛除非素数有一个非素数不能筛掉,那就是1,所以如果L是1,必须另外处理。

        随便说一句,存储素数的数组该开多大呢,可以用X/㏑X(计算小于X的素数个数)来辅助判断,那个公式只是估计值,一般是偏小,所以必须在此基础上往大里开。

        最后谈一下我犯的错误。

        开始我的一段代码是如下这样:

k=sqrt(MAX*1.0);
for(i=2;i<=k;i++)
{  
    if(array[i])
    {     
        prime[len++]=i;         
        for(j=i+i;j<MAX;j+=i) array[j]=false;                                             
    }              
}

        这里本来想省事,在发现素数时顺便存下来,可是错误在于这里只是存了[2,k]内的素数,而不是[2,MAX]内的素数,检查错误时一直没想到这里会错,导致WA很多次,所以下次对自己很熟悉的地方也不要太大意,尤其是想找到这个问题很简单,输出就能发现,可惜一开始一直很懒,不愿进行输出检查。不过如果想在筛素数时同时存储下来,可以把k换成MAX-1。


AC代码(C++):

#include <cstdlib>
#include <iostream>
#include <cmath>

#define INF 2147483647
#define MAX 50001 

using namespace std;

bool array[MAX],array2[1000002];

long long prime[5000],prime2[80000],len,len2;

void mkprime()
{
     long long i,j,k;
     k=sqrt(MAX*1.0);
     len=0;
     memset(array,true,sizeof(array));
     for(i=2;i<=k;i++)
     {
          if(array[i])
          {             
              for(j=i+i;j<MAX;j+=i) array[j]=false;                                             
          }              
     }
     
     for(i=2;i<MAX;i++)
     {
        if(array[i]) prime[len++]=i;
     }
}

int main(int argc, char *argv[])
{
    long long L,U,i,dis1,dis2,a,b,c,d,tmp;
    long long j;
    mkprime();
    while(cin>>L>>U)
    {
        memset(array2,true,sizeof(array2));
        
        for(i=0;i<len;i++)
        {                        
            if(prime[i]>=L) j=2*prime[i]-L;
            else{  
                tmp=L/prime[i];                
                j=tmp*prime[i]-L;
                while(j<0) j+=prime[i];
            }   
            
            //下面这种也可以 
            /*tmp=L/prime[i];
            while(tmp*prime[i]<L||tmp<=1) tmp++;
            j=tmp*prime[i]-L;  */      
             
            for(;j<U-L+1;j+=prime[i]) array2[j]=false;
        }
        
        if(1==L) array2[0]=false;
        
        len2=0;
        dis1=INF;
        dis2=-INF;
        for(i=0;i<U-L+1;i++)
        {
           if(array2[i])
           {
              prime2[len2++]=i;              
              
              if(len2>1)
              {
                  if(prime2[len2-1]-prime2[len2-2]<dis1)      
                  {
                      dis1=prime2[len2-1]-prime2[len2-2];
                      a=len2-2;
                      b=len2-1;
                  }
                  if(prime2[len2-1]-prime2[len2-2]>dis2)
                  {
                      dis2=prime2[len2-1]-prime2[len2-2];
                      c=len2-2;
                      d=len2-1;
                  }
              }
           }
        }
        if(len2>1) cout<<prime2[a]+L<<','<<prime2[b]+L<<" are closest, "<<prime2[c]+L<<','<<prime2[d]+L<<" are most distant."<<endl;
        else cout<<"There are no adjacent primes."<<endl;
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

题目:

Prime Distance
Time Limit: 1000MS Memory Limit: 65536K
   

Description

The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousands of years is the question of primality. A prime number is a number that is has no proper factors (it is only evenly divisible by 1 and itself). The first prime numbers are 2,3,5,7 but they quickly become less frequent. One of the interesting questions is how dense they are in various ranges. Adjacent primes are two numbers that are both primes, but there are no other prime numbers between the adjacent primes. For example, 2,3 are the only adjacent primes that are also adjacent numbers. 
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).

Input

Each line of input will contain two positive integers, L and U, with L < U. The difference between L and U will not exceed 1,000,000.

Output

For each L and U, the output will either be the statement that there are no adjacent primes (because there are less than two primes between the two given numbers) or a line giving the two pairs of adjacent primes.

Sample Input

2 17
14 17

Sample Output

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



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值