zoukankan      html  css  js  c++  java
  • 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;
    }
     
  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2653311.html
Copyright © 2011-2022 走看看