HDU 1406 完数(水题)

 

完数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11766    Accepted Submission(s): 4082


Problem Description
完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。

本题的任务是判断两个正整数之间完数的个数。
 

 

Input
输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000) 。
 

 

Output
对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。
 

 

Sample Input
2 2 5 5 7
 

 

Sample Output
0 1
 

 

Author
lcy
 

 

Source
 

 

Recommend
Ignatius.L
 
 
 
虽然我做的比较复杂,好像直接枚举所有的1~n-1的数来判断约数都可以过的。
我练习下合数分解,然后求的所有因子的和
 
/*

HDU 1406

*/

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

using namespace std;



//******************************************

//素数筛选和合数分解

const int MAXN=10000;

int prime[MAXN+1];

void getPrime()

{

    memset(prime,0,sizeof(prime));

    for(int i=2;i<=MAXN;i++)

    {

        if(!prime[i])prime[++prime[0]]=i;

        for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)

        {

            prime[prime[j]*i]=1;

            if(i%prime[j]==0) break;

        }

    }

}

long long factor[100][2];

int fatCnt;

int getFactors(long long x)

{

    fatCnt=0;

    long long tmp=x;

    for(int i=1;prime[i]<=tmp/prime[i];i++)

    {

        factor[fatCnt][1]=0;

        if(tmp%prime[i]==0)

        {

            factor[fatCnt][0]=prime[i];

            while(tmp%prime[i]==0)

            {

                factor[fatCnt][1]++;

                tmp/=prime[i];

            }

            fatCnt++;

        }

    }

    if(tmp!=1)

    {

        factor[fatCnt][0]=tmp;

        factor[fatCnt++][1]=1;

    }

    return fatCnt;

}



//******************************************

long long pow_m(long long a,long long n)//快速幂运算

{

    long long res=1;

    long long tmp=a;

    while(n)

    {

        if(n&1)res*=tmp;

        n>>=1;

        tmp*=tmp;

    }

    return res;

}

long long sum(long long p,long long n)//计算1+p+p^2+````+p^n

{

    if(p==0)return 0;

    if(n==0)return 1;

    if(n&1)//奇数

    {

        return ((1+pow_m(p,n/2+1))*sum(p,n/2));

    }

    else return (1+pow_m(p,n/2+1))*sum(p,n/2-1)+pow_m(p,n/2);

}

bool judge(int n)

{

    getFactors(n);

    int temp=1;

    for(int i=0;i<fatCnt;i++)

       temp*=sum(factor[i][0],factor[i][1]);

    if(2*n==temp)return true;

    else return false;

}

bool a[10010];

int main()

{

    //freopen("in.txt","r",stdin);

    //freopen("out.txt","w",stdout);

    getPrime();

    for(int i=1;i<=10000;i++)a[i]=judge(i);

    int m,n;

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d%d",&m,&n);

        if(m>n)swap(m,n);

        int ans=0;

        for(int i=m;i<=n;i++)

          if(a[i])ans++;

        printf("%d\n",ans);

    }

    return 0;

}

 

 

 

 

你可能感兴趣的:(HDU)