1716: Divisors(素数筛选)

 

Status In/Out TIME Limit MEMORY Limit Submit Times Solved Users JUDGE TYPE
stdin/stdout 3s 8192K 266 100 Standard

Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an interesting number, since it is the first odd number for which the sum of its divisors is larger than the number itself.

 

To help them search for interesting numbers, you are to write a program that scans a range of numbers and determines the number that has the largest number of divisors in the range. Unfortunately, the size of the numbers, and the size of the range is such that a too simple-minded approach may take too much time to run. So make sure that your algorithm is clever enough to cope with the largest possible range in just a few seconds.

Input Specification

The first line of input specifies the number N of ranges, and each of the N following lines contains a range, consisting of a lower bound L and an upper bound U, where L and U are included in the range. L and U are chosen such that and .

Output Specification

For each range, find the number P which has the largest number of divisors (if several numbers tie for first place, select the lowest), and the number of positive divisors D of P (where P is included as a divisor). Print the text 'Between L and H, P has a maximum of D divisors.', where L, H, P, and D are the numbers as defined above.

Example input

 

3
1 10
1000 1000
999999900 1000000000

Example output

 

Between 1 and 10, 6 has a maximum of 4 divisors.
Between 1000 and 1000, 1000 has a maximum of 16 divisors.
Between 999999900 and 1000000000, 999999924 has a maximum of 192 divisors.

 

 

Submit / Problem List / Status / Discuss

 

所谓有素数筛选法,就是从2(最小的素数)开始往上进行筛选,把所有质数的整倍数都剔除掉,最后剩下来的就是素数了。当然这不是最好最快的方法,占用的空间也不小,不过这种方法简单易行,运行效率也不是太低——比起最普通的用函数判断每个数那也是天壤之别了,所以还是非常常用的。

有一处优化:筛选i的倍数时,可以直接从i^2开始筛选,因为比i^2小的倍数已经被比i小的素数给筛选掉了,因为这样,外层循环也可以只累加到sqrt(n)即可。另外一个Re_storage函数将素数表进行转存,便于某些情况下的访问,prime_count保存素数的个数

 

#include<iostream>
#include<math.h>
#define maxn 1000000000;
bool isprime[32000];
int prime[15000],num[15000];
int prime_count;
void Make()
{
       int i,j;
       memset(isprime,true,sizeof(isprime));
       isprime[0] = isprime[1] = false;
       for (i=2;i<180;i++)
    {
              if(isprime[i])
     {
                     for(j=i*i;j<32000;j+=i)
                            isprime[j]=false;
              }
       }
}
void Re_storage ()
{
       prime_count=0;
       for (int i=2;i<32000;i++)
    {
              if(isprime[i])
                    prime[prime_count++]=i ;
       }
}
int main()
{
 freopen("in.txt","r",stdin);
 freopen("out.txt","w",stdout);
 int n,i,j,l,u,count,m;
 int max,k,k2;
 Make();
 Re_storage();
 scanf("%d",&n);
 while(n--)
 {
  max=-1;
  scanf("%d%d",&l,&u);
  for(i=l;i<=u;i++)
  {
     memset(num,0,sizeof(num));
     int x=(int)sqrt(i);
     count=0;
     m=i;
     for(j=0;prime[j]<=x;j++)    
   {     
    if(i%prime[j]!=0)continue;     
    while(m%prime[j]==0)     
    {      
     num[count]++;      
     m/=prime[j];     
    }     
    count++;     
    if(m==1)break;    
   } 
     if(m>1)
    num[count++]=1;
     k2=1;
     for(j=0;j<count;j++)
         k2=k2*(num[j]+1);
        if(max<k2)
        {
    max=k2;
    k=i;
     }  
  }
   printf("Between %d and %d, %d has a maximum of %d divisors./n",l,u,k,max);
 }
 return 0;
}

你可能感兴趣的:(Algorithm,properties,search,input,each,Numbers)