项目欧拉#21

时间:2016-04-06 00:08:04

标签: c# algorithm oop

条件:

  

设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。

     

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

我做了以下事情:

    static void Main()
    {
        long sum = 0;
        List<int> passedValues = new List<int>();
        for (int i = 1; i < 10000; i++)
        {
            var number1 = SumOfNumber(i);
            var number2 = SumOfNumber(SumOfNumber(i));
            if (number2 == i && !passedValues.Contains(number1))
            {
                sum = sum + number1;
                passedValues.Add(number1);
                passedValues.Add(number2);
            }
        }
        Console.WriteLine(sum);
        Console.ReadKey();
    }

    private static int SumOfNumber(int input)
    {
        int sum = 0;
        for (int i = 1; i <= input/2; i++)
        {
            if (input%i == 0)
            {
                sum += i;
            }
        }
        return sum;
    }

然而它给出结果40284,而正确的答案似乎是31626为什么我的程序不能正常工作?我多次添加一些东西吗?我还尝试添加一个列表来存储传递的值,但最终得到的结果是25008:

static void Main()
    {
        long sum = 0;
        List<int> passed = new List<int>();
        for (int i = 1; i < 10000; i++)
        {
            var number1 = SumOfNumber(i);
            var number2 = SumOfNumber(SumOfNumber(i));
            if (number2 == i && !passed.Contains(i))
            {
                sum = sum + number1;
                passed.Add(number1);
            }
        }
        Console.WriteLine(sum);
        Console.ReadKey();
    }

3 个答案:

答案 0 :(得分:2)

这里有两个问题:

  1. 您不是将两个友好对号添加到总和中。
  2. 你包含了完整的数字(其中d(n)= n),因为违反了≠b,所以不具备友好对的资格。
  3. 我认为当你没有添加列表来存储传递的数字时,你就更接近了,因为这导致了问题#1,因为你只是将number1的贡献添加到总和中,但是添加了列表中包含number1number2,最终导致number2被跳过。要解决问题#2,您还需要验证number1 != number2。例如:

    if (number2 == i && number1 != number2)
                     ^^^^^^^^^^^^^^^^^^^^^ add this check
    {
        sum = sum + i;
    

    将这两个修复程序应用于您提供的代码后,我得到的预期总数为31626.

答案 1 :(得分:2)

我的结果为31626.这里的区别在于如何防止总和中出现重复。而不是保存到列表中,只是为了确保我总是小于number1。

 static void Main()
    {

        long sum = 0;
        List<int> passedValues = new List<int>();
        for (int i = 1; i < 10000; i++)
        {
            var number1 = SumOfNumber(i);
            var number2 = SumOfNumber(SumOfNumber(i));


            if (number2 == i && i < number1)
            {
                sum = sum + i + number1;

            }
        }
        Console.WriteLine(sum );
        Console.ReadKey();
    }

    private static int SumOfNumber(int input)
    {
        int sum = 0;
        for (int i = 1; i <= input / 2; i++)
        {
            if (input % i == 0)
            {
                sum += i;
            }
        }
        return sum;
    }

答案 2 :(得分:0)

private static int SumOfNumber(int input)
{
    int sum = 0;
    for (int i = 1; i <= input/2; i++)
    {
        if (input%i == 0)
        {
            sum += i;
        }
    }
    return sum;
}

这不正确。您只是添加其中一个因素,而不是循环到数字的sqrt。