2016-04-06 17 views
2

Состояние:Проект Эйлера # 21

Пусть д (п) определяется как сумма собственных делителей п (числа меньше, чем п, которые делят равномерно на п). Если 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(); 
    } 
+0

http://www.mathblog.dk/project-euler-21-sum-of-amicable-pairs/ –

+3

Если бы я хотел скопировать пасту, то я не собирался публиковать здесь помощь – KOPEUE

+0

Ну что ж, , ваш код просто не решает проблему. Пройдите через него, и вы узнаете, почему. Вы должны найти виновника с менее чем десятью нажатиями клавиш f10. – SimpleVar

ответ

2

Есть две проблемы:

  1. Вы не добавляющие как дружные номера пары к сумме.
  2. Вы включаете в себя идеальные числа (где d (n) = n), которые не квалифицируются как дружественные пары, поскольку нарушается ≠ b.

Я думаю, вы были ближе, когда вы не добавили в список для хранения передаваемых чисел, потому что вызвало вопрос # 1 выше, так как вы добавляете только вклад number1 в сумме, но добавление как number1 и number2, в результате чего number2 в конечном итоге будет пропущен. Для решения проблемы № 2 вам также необходимо подтвердить number1 != number2. Например:

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

После применения обоих этих исправлений для вашего кода при условии, я получаю ожидаемый итог 31626.

+0

Я полностью удалил 'passValues', потому что это не нужно. Вы видите только одно значение один раз, поэтому не должно быть никаких дубликатов. Однако вы хотите добавить 'i' или' number2', а не 'number1'. Подумайте о случае, когда <10000 и b> 10000. Вы добавили бы 'b' к сумме, но это не удовлетворяет условию, что вы добавляете дружественные номера <10000.К счастью, никакие дружественные пары не имеют одного номера <10000 и одного> 10000, так что это не проблема. – mellamokb

2

я получил результат, 31626. Разница здесь в том, как предотвратить дубликата в сумма. Вместо сохранения в списке просто убедитесь, что i всегда меньше числа 1.

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

Это тоже неплохое решение, так как красиво и безупречно! Приветствия :) – mellamokb

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 этого числа.

Смежные вопросы