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
杭电ACM集训队训练赛(IV)  

 

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;
}

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/archive/2012/08/23/2653311.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞