Проект Эйлера (21 задача) внешне крайне простая, однако она имеет широкие возможности для оптимизации и ускорения.
Узнать больше в телеграм-канале: ProjectEuler++
Пусть 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.
Измеряем время работы программы
Функция для расчета суммы делителей числа
Будем сохранять вычисления, потому что это позволит не вычислять одно и тоже повторно и в итоге сократит время работы программы. Для этого создадим массив, в котором будем хранить суммы делителей числа по их индексу.
Далее алгоритм простой (смотрите выше).
Например, сумма делителей числа 220 равна 284.
При этом сразу же каждое число проверяем на то, нет ли у него дружественных чисел (смотрите задание). Для этого обращаемся к массиву. Например, для числа 284:
Сумма делителей числа 284 это 220. И такая конструкция:
…будет означать:
Проверив, после чего, числа на неравенство:
Получаем в итоге, что числа 284 и 220 являются дружественными. Прибавляем потому их к искомой сумме.
При этом пары чисел не будут дублироваться (284 и 220) и (220 и 284). Так будет происходить, потому что когда перебор чисел доходит до меньшего из пары дружественных чисел (220), сумма делителей большего (284) еще не вычислена значение в массиве равно нулю.
Для измерения времени работы программы подключаем библиотеку time.h:
С помощью функции clock() измеряем время начала (begin) и окончания (end) работы программы. В итоге время работы будем находить как разность между ними.
(double) приводит число (в данном случае – результат вычислений end – begin) к вещественному типу данных double (числа с точкой)
CLOCKS_PER_SEC – это константа, сохраненная в библиотеке и зависящая от типа устройства, на котором запускается программа. В данном случае – это просто 1000
Поскольку в дальнейшем эта функция может быть применена в других программах, то контекст может измениться. Потому, чтобы избежать неправильной работы, в ней сделана проверка корректности принимаемого значения.
В итоге значения чисел, выходящие за рамки, на которые рассчитана функция, она считать не будет и сразу вернет 0.
Однако программа при этом не прервется, просто будут считаться произведения следующих чисел. Потому, чтобы не гадать потом о причинах некорректного ответа, функция выведет свое название, некорректное число и предупреждение об ошибке в консоль.
По традиции хотелось бы выразить глубочайшую признательность Сергею Балакиреву за его титанический труд по созданию бесплатных курсов и в частности, за “Язык программирования C/C++ для начинающих“.
© 2023-2024 | eulerproject.ru