HackerRank Project Euler#21:友善号码

时间:2015-06-02 11:15:39

标签: c

Here是问题陈述。

  

d(n)定义为n的适当除数之和(小于n的数均匀分为n)。

     

如果 d(a)= b d(b)= a ,其中 a≠b ,那么a和b是友好对和a和b中的每一个被称为友好数字。

     

例如,220的适当除数是1,2,4,5,10,11,20,22,44,55和110因此d(220)= 284。 284的适当除数是1,2,4,71和142,所以d(284)= 220。

     

评估N下所有友好数字的总和。

这是我的蛮力代码

#include <stdio.h>

long long int sum(long long int n)
{
    long long int i, sum=0;
    for(i=1;i<n;i++)
    {
        if(n%i==0)
            sum+=i;
    }
    return sum;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long int n;
        scanf("%lld",&n);
        long long int i,sum1=0;
        for(i=1;i<n;i++)
        {
            if(sum(sum(i))==i&&sum(i)!=i)
                sum1+=i;
        }
        printf("%lld\n",sum1);
    }
    return 0;
}

此代码有效,但速度很慢。因此,我实现了更快的算法。

该算法将找到其素因子的除数之和并将它们相乘。该算法的证明here。这是代码。

#include <stdio.h>

long long int power(long long int x, long long int y)
{
    long long int i,a=1;
    for(i=1;i<=y;i++)
        a*=x;
    return a;
}

long long int sumOfPrimeDivisors(long long int p, long long int a)
{
    long long int x;
    x=(power(p,a+1)-1)/(p-1);
    return x;
}

long long int isPrime(long long int n)
{
    long long int i,flag=1;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            flag=0;
            break;
        }
    }
    return flag;
}

void primeDivisors(long long int n, long long int b[], int *k)
{
    long long int i;
    *k=0;
    for(i=2;i<n;i++)
    {
        if(n%i==0 && isPrime(i))
        {
        b[(*k)++]=i;
        }
    }
}

long long int primeDivisorCount(long long int n, long long int p)
{
    long long int count=0;
    while(n%p==0)
    {
        count++;
        n/=p;
    }
    return count;
}

long long int sum(long long int n)
{
    long long int ans=1,b[15];
    int k,i;

    primeDivisors(n,b,&k);

    for(i=0;i<k;i++)
        ans*=sumOfPrimeDivisors(b[i],primeDivisorCount(n,b[i]));

    return ans-n;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long int n;
        scanf("%lld",&n);

        printf("%lld %lld\n",sum(n),sum(sum(n)));
    }

    return 0;
}

此代码为n=220 (284 220)提供了正确的输出。但是当我用

替换printf
long long int i;

        for(i=1;i<n;i++)
        {
            if(sum(sum(i))==i && sum(i)!=i )
                printf("%lld\n",i);
        }

我得到输出的所有垃圾值。

例如,

  

输入

1
9949
     

输出

-9948

我做错了什么?

2 个答案:

答案 0 :(得分:2)

更改

if(sum(sum(i))==i && sum(i)!=i )

if(sum(sum(i))==i && sum(i)!=i && sum(i)>0)

帮助提供正确的输出。

答案 1 :(得分:1)

使用此代替printf:

{{1}}

以前所有其他素数也都在显示。