Проект Эйлера (25 задача) имеет крайне простой алгоритм решения, однако дает прекрасную возможность поработать с большими числами.
Узнать больше в телеграм-канале: ProjectEuler++
Последовательность Фибоначчи определяется рекурсивным правилом:
Fn = Fn−1 + Fn−2, где F1 = 1 и F2 = 1.Таким образом, первые 12 членов последовательности равны:
F1 = 1
F2 = 1
F3 = 2
F4 = 3
F5 = 5
F6 = 8
F7 = 13
F8 = 21
F9 = 34
F10 = 55
F11 = 89
F12 = 144Двенадцатый член F12 – первый член последовательности, который содержит три цифры.
Каков порядковый номер первого члена последовательности Фибоначчи, содержащего 1000 цифр?
Поскольку речь в задаче идет о 1000-значных числах, потому для хранения чисел понадобится массив. Однако в этот раз решил сделать не просто char-массив длиной 1000, а более полноценную структуру данных (смотрите выше).
Она включает в себя:
Поскольку в данном случае мы работаем с числами Фибоначчи, потому также храним:
Для хранения относительного расположения применяем перечисление enum. Оно будет принимать всего два значения: prev и next.
На самом деле в памяти будут храниться числа 0 и 1, однако применение именно перечисления имеет свои преимущества:
Поскольку очередное число Фибаначчи вычисляется, как сумма предыдущих:
… потому для вычисления ответа нам понадобится всего два числа: предыдущее число (prev) и следующее за ним (next).
Задаем первых два числа:
Вычисляем следующее число:
Переопределяем порядок чисел:
Далее алгоритм повторяется (смотрите скриншот выше):
… до тех пор, пока длина очередного числа не достигнет искомой 1000 знаков.
При этом нет необходимости в дополнительных счетчиках и переменных, потому что все необходимые данные хранит структура “большого числа”.
Для измерения времени работы программы подключаем библиотеку time.h:
С помощью функции clock() измеряем время начала (begin) и окончания (end) работы программы. В итоге время работы будем находить как разность между ними.
(double) приводит число (в данном случае – результат вычислений end – begin) к вещественному типу данных double (числа с точкой)
CLOCKS_PER_SEC – это константа, сохраненная в библиотеке и зависящая от типа устройства, на котором запускается программа. В данном случае – это просто 1000
Поскольку при создании структуры начальные данные не инициализируются, потому создадим отдельную функцию для этого.
Функция “отрезает “от числа младший разряд до тех пор, пока число “не кончится”. Количество разрядов в итоге и возвращается как длина числа.
По сути ее короткий код можно было просто включить в другие функции. Однако, руководствуясь принципом DRY “не повторяй себя дважды”, все-таки вынес ее, чтобы не дублироваться.
Функция принимает два “больших” числа и, по сути, просто складывает числа в двух массивах столбиком. При этом:
После завершения сложения чисел:
Также в функции контролируется правильность порядка задания аргументов функции (next и prev), а также выход числа за пределы массива.
Как ясно из названия, функция сравнивает два значения.
Если контролируемое значение превысит свой предел, то функция вернет true и выведет предупреждение.
Иначе вернет false.
Очень простая, однако, очень важная и полезная функция. Помогает как при отладке, так и при повторном использовании функций в других программах. Поскольку в других задачах другие условия, потому контекст применения функций может поменяться. Потому важно ограничивать параметры принимаемых функцией значений и выводить соответствующие предупреждения.
По традиции хотелось бы выразить глубочайшую признательность Сергею Балакиреву за его титанический труд по созданию бесплатных курсов и в частности, за “Язык программирования C/C++ для начинающих“.
© 2023-2024 | eulerproject.ru