Проект Эйлера (12 задача) не требует навороченного алгоритма вычисления, однако чтобы найти ответ за приемлемое время потребуются ухищрения.
Узнать больше в телеграм-канале: ProjectEuler++
Последовательность треугольных чисел образуется путем сложения натуральных чисел. К примеру, 7-е треугольное число равно 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. Первые десять треугольных чисел:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …
Перечислим делители первых семи треугольных чисел:
1: 1
3: 1, 3
6: 1, 2, 3, 6
10: 1, 2, 5, 10
15: 1, 3, 5, 15
21: 1, 3, 7, 21
28: 1, 2, 4, 7, 14, 28Как мы видим, 28 – первое треугольное число, у которого более пяти делителей.
Каково первое треугольное число, у которого более пятисот делителей?
Прежде всего не будем вычислять каждое треугольное число так, как это указано в задании.
Потому что можно сделать проще – к предыдущему треугольному числу прибавлять натуральное таким образом:
Самым простым способом будет перебрать все делители от единицы до самого числа и те, которые делятся нацело, посчитать.
Однако вычисляться это будет целую вечность. Потому применим несколько хитростей (смотрите выше).
Во-первых, если число имеет делитель, то его можно разложить на два числа. Возьмем, для примера число 36:
Потому, получая делитель числа 1 (назовем его минимальный) мы сразу же получаем второй делитель – 36 (максимальный), для 2 получаем 18, 3 – 12 и так далее.
Во-вторых, после квадратного корня из числа делители начнут повторяться (для числа из примера 36 – после 6). Потому подсчет делителей идет только до sqrt() из числа.
В-третьих, функцию sqrt() необходимо вынести перед циклом for. Это необходимо делать потому, что некоторые компиляторы будут вычислять sqrt() на каждой итерации цикла. Конкретно для моего компилятора и этой конкретной задачи разница во времени работы программы составила в двадцать раз.
В-четвертых, иногда число раскладывается на два одинаковых числа (36 = 6 * 6). Потому этот случай необходимо считать как один найденный делитель.
Подключаем стандартную математическую библиотеку языка Си. Необходима для работы функции sqrt()
Для измерения времени работы программы подключаем библиотеку time.h:
С помощью функции clock() измеряем время начала (begin) и окончания (end) работы программы. В итоге время работы будем находить как разность между ними.
(double) приводит число (в данном случае – результат вычислений end – begin) к вещественному типу данных double (числа с точкой)
CLOCKS_PER_SEC – это константа, сохраненная в библиотеке и зависящая от типа устройства, на котором запускается программа. В данном случае – это просто 1000
По традиции хотелось бы выразить глубочайшую признательность Сергею Балакиреву за его титанический труд по созданию бесплатных курсов и в частности, за “Язык программирования C/C++ для начинающих“.
© 2023-2024 | eulerproject.ru