UVa 294 - Divisors 解题报告 c语言实现 素数筛法

1.题目大意:

输入两个整数L、H其中($1≤L≤H≤10^9,H−L≤10000$),统计[L,H]区间上正约数最多的那个数P(如有多个,取最小值)以及P的正约数的个数D。

 

2.原理:

对于任意的一个正整数N,若有$N=p_1^{e1}p^{e2}_2...p^{er}_r$ 且$p_1、p_2...p_r$都为素数,则有N的因数个数为$(e1+1)(e2+1)...(er+1)$。

 

3.范围确定

关于对maxn的确定,由$1≤L≤H≤10^9$可知:对 $10^9$ 开根号,大概估算一下,将maxn取32000。

 

4.思路

考虑先素数筛法打表得出32000以内所有素数,然后把因数个数求出来,若大于之前出现过的最大因子数,则修改;反之,不变。

 

5.代码:

#include"stdio.h"
#define maxn 32000
int prime[maxn],origin[maxn];

int getfactor(int* prime ,int i)// 求出因数个数
{
    int sum=1,count;
    for(int j=1; j<prime[0]&&i!=1; j++)
        if(i%prime[j]==0)
        {
            count=1;
            while(i%prime[j]==0)
            {
                count++;
                i/=prime[j];
            }
            sum*=count;
        }
    return sum;
}

int main()
{
    /* 利用素数筛法得出32000以内所有素数 存入prime数组中 */
    for(int i=0; i<maxn; i++)
        origin[i]=1;
    for(int i=2; i<maxn; i++)
        if(origin[i])
            for(int j=2*i; j<maxn; j+=i)
                origin[j]=0;
    prime[0]=0;
    for(int i=2; i<maxn; i++)
        if(origin[i])
            prime[++prime[0]]=i; // 用prime[0]表示素数个数

    /* 利用getfactor函数得出因子数 ,
    若大于之前出现过的最大因子数,则存入d. */
    int t,n,l,h,p,d;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&l,&h);
        d=0;
        for(int i=l; i<=h; i++)
        {
            n=getfactor(prime,i);
            if(n>d)
            {
                d=n;
                p=i;
            }
        }
        printf("Between %d and %d, %d has a maximum of %d divisors.\n",l,h,p,d);
    }
    return 0;
}

  

posted @ 2016-09-02 13:04  rgvb178  阅读(1442)  评论(0编辑  收藏  举报