Добавить в корзинуПозвонить
Найти в Дзене
МОЙ РЕПЕТИТОР

ПОЛНЫЙ ГАЙД ПО РЕКУРСИВНЫМ ФУНКЦИЯМ В PYTHON: ЧАСТЬ 6 (HARD)

→ Данный материал продолжает тему изучения рекурсивных функций и является прямым продолжением предыдущих частей (ЧАСТЬ 1, ЧАСТЬ 2, ЧАСТЬ 3, ЧАСТЬ 4, ЧАСТЬ 5). ✅ В этой статье представлен подробный разбор решения очень интересной задачи формата ЕГЭ по информатике. ДАННЫЙ ПРИМЕР ОТЛИЧАЕТСЯ ПОВЫШЕННОЙ СЛОЖНОСТЬЮ❗ Выполнение задачи потребует применения разных стратегий и способов решения. 🚥HERE WE GO → Необходимо 2 - 3 раза внимательно прочитать условие задачи ⤵ 📝 Текст условия для копирования: Обозначим через a % b остаток от деления натурального числа a на натуральное число b, а через a // b  — целую часть от деления a на b. Функция F(n), где n  — неотрицательное целое число, задана следующими соотношениями: F(n)  =  0, если n  =  0; F(n)  =  F(n // 10)  +  n % 10, если n > 0 и n чётно; F(n)  =  F(n // 10), если n нечётно. Определите количество таких целых k, что 10^9 ≤ k ≤ 2 · 10^9 и F(k)  =  2. После прочтения данного ⇪ материала важно выделить ключевые моменты → В данной задаче уд
Оглавление

→ Данный материал продолжает тему изучения рекурсивных функций и является прямым продолжением предыдущих частей (ЧАСТЬ 1, ЧАСТЬ 2, ЧАСТЬ 3, ЧАСТЬ 4, ЧАСТЬ 5).

✅ В этой статье представлен подробный разбор решения очень интересной задачи формата ЕГЭ по информатике.

ДАННЫЙ ПРИМЕР ОТЛИЧАЕТСЯ ПОВЫШЕННОЙ СЛОЖНОСТЬЮ❗

Выполнение задачи потребует применения разных стратегий и способов решения.

🚥HERE WE GO →

УСЛОВИЕ ЗАДАЧИ

Необходимо 2 - 3 раза внимательно прочитать условие задачи

Условие задачи.
Условие задачи.

📝 Текст условия для копирования:

Обозначим через a % b остаток от деления натурального числа a на натуральное число b, а через a // b  — целую часть от деления a на b.
Функция F(n), где n  — неотрицательное целое число, задана следующими соотношениями:
F(n)  =  0, если n  =  0;
F(n)  =  F(n // 10)  +  n % 10, если n > 0 и n чётно;
F(n)  =  F(n // 10), если n нечётно.
Определите количество таких целых k, что 10^9 ≤ k ≤ 2 · 10^9 и F(k)  =  2.

После прочтения данного ⇪ материала важно выделить ключевые моменты →

КЛЮЧЕВЫЕ МОМЕНТЫ ИЗ УСЛОВИЯ

В данной задаче удалось выделить 3 ключевых пункта ⤵

  • РЕКУРРЕНТНАЯ ФОРМУЛА
Важный момент из условия задачи. Рекуррентная формула.
Важный момент из условия задачи. Рекуррентная формула.
Рекуррентная формула (соотношение) — это алгоритм в рекурсивной функции, по которому каждое новое значение считается через предыдущие значения.

Работа алгоритма в этой задаче определяется данными рекуррентными формулами:

  • F(n) = F(n // 10) + n % 10, если n > 0 и n чётно
  • F(n) = F(n // 10), если n нечётно

Переходим к следующему важному пункту

  • УСЛОВИЕ ДЛЯ ОСТАНОВКИ РЕКУРСИВНОЙ ФУНКЦИИ
Важный момент из условия задачи. Условие для выхода из рекурсивной функции.
Важный момент из условия задачи. Условие для выхода из рекурсивной функции.
Условие остановки (условие выхода) — это условие, при котором функция перестаёт вызывать саму себя.

🚨БЕЗ УСЛОВИЯ ОСТАНОВКИ ФУНКЦИЯ БУДЕТ ВЫЗЫВАТЬ САМУ СЕБЯ БЕСКОНЕЧНОЕ КОЛИЧЕСТВО РАЗ.

В данной задаче условие для выхода из рекурсии:

  • F(0) = 0, если n = 0

Переходим к следующему важному пункту

  • ГЛАВНЫЙ ВОПРОС ИЛИ ЧТО НУЖНО НАЙТИ В ЗАДАЧЕ
Важный момент из условия задачи. Что нужно найти или вычислить.
Важный момент из условия задачи. Что нужно найти или вычислить.

→ В данной задаче необходимо определить количество целых (k) из промежутка от 10 ^ 9 до 2 * 10 ^ 9 и F(k) = 2

F(k) — значение функции F с аргументом, равным (k).

👏 Good! Теперь переходим к решению задачи

РЕШЕНИЕ ЗАДАНИЯ ЧЕРЕЗ PYTHON

Решение будет включать в себя 4 основных этапа 🔽

  • СОЗДАНИЕ РЕКУРСИВНОЙ ФУНКЦИИ
  • ПЕРЕМЕННАЯ ДЛЯ ПОДСЧЁТА ЗНАЧЕНИЙ
  • ЗАПУСК ЦИКЛА for
  • ВЫВОД РЕЗУЛЬТАТА НА ЭКРАН

Переходим к первому этапу

🔹 СОЗДАНИЕ РЕКУРСИВНОЙ ФНУКЦИИ

Необходимо создать функцию, в которой и будет реализован рекурсивный алгоритм ⤵

🚀 КОД ПРОГРАММЫ:

Первый этап решения задачи. Создание рекурсивной функции.
Первый этап решения задачи. Создание рекурсивной функции.
  • ОСНОВНЫЕ МОМЕНТЫ:

def — служебное слово для создания функций в Python.

return — завершает работу функции и возвращает результат туда, где функцию вызвали.

→ Для правильной записи рекурсивной функции необходимо учесть важные моменты из условия:

  • РЕКУРРЕНТНАЯ ФОРМУЛА
  • УСЛОВИЕ ДЛЯ ОСТАНОВКИ РЕКУРСИВНОЙ ФУНКЦИИ
Рекуррентная формула и условие для остановки рекурсии в программе на Python.
Рекуррентная формула и условие для остановки рекурсии в программе на Python.

  • Рекурсивная функция записана. Как проверить, что она работает?

— Запустить функцию.

→ Для промежуточной проверки можно взять любое значение, например 287. И далее, вызвать функцию в основной программе с этим значением ↓

Проверка работы функции (F). Функция запущена с аргументом, равным (287).
Проверка работы функции (F). Функция запущена с аргументом, равным (287).

print(F(287)) — вызов функции (F) с аргументом (287).

При обработке числа 287 функция вернула значение 10. Подробное объяснение этого результата рассмотрим позже.

👉 СЛЕДУЮЩИЙ ЭТАП →

🔹 ПЕРЕМЕННАЯ ДЛЯ ПОДСЧЁТА ЗНАЧЕНИЙ

Необходимо ввести дополнительную переменную, которая и будет являться ответом к задаче

🚀 КОД ПРОГРАММЫ:

Второй этап решения задачи. Инциализация переменной для подсчёта значений.
Второй этап решения задачи. Инциализация переменной для подсчёта значений.

b — имя переменной для подсчёта подходящих вариантов (счётчик).

Счётчик — это переменная, предназначенная для подсчёта количества определённых событий или значений в процессе выполнения программы.
  • Как работает счётчик?

Каждый раз как происходит определённое событие или выполняется условие переменная увеличивается на 1 ↓

-10
Счётчик — число, которое меняется по мере работы программы.

→ Значение переменной счётчика можно увеличивать или уменьшать на заданное число, например:

c += 2 — увеличение переменной (с) на 2.

k -= 3 — уменьшение переменной (k) на 3.

Несколько примеров по работе данной переменной для лучшего понимания

❶ ПОДСЧЁТ КОЛИЧЕСТВА ЧЁТНЫХ ЧИСЕЛ

Код программы для подсчёта чётных чисел с использованием переменной счётчика.
Код программы для подсчёта чётных чисел с использованием переменной счётчика.

b = 0 — инциализация (создание) переменной в программе.

b += 1 — каждый раз при выполнении условия, переменная будет увеличиваться на 1.

% — остаток от деления в Python.

❷ ПОДСЧЁТ КОЛИЧЕСТВА ДВУХЗНАЧНЫХ ЧИСЕЛ, НАЧИНАЮЩИХСЯ С ЦИФРЫ 2

-12
  • Всего двузначных чисел, начинающихся с цифры 2:

20, 21, 22, 23, 24, 25, 26, 27, 28, 29 (10 чисел)

// — целочисленное деление в Python.

👉 СЛЕДУЮЩИЙ ЭТАП →

🔹 ЗАПУСК ЦИКЛА for

Для вычисления значений функции (F) ⤵

🚀 КОД ПРОГРАММЫ:

Третий этап решения задачи. Запуск цикла (for).
Третий этап решения задачи. Запуск цикла (for).
  • Зачем цикл (for) в данной программе?

— Чтобы перебрать все возможные значения для переменной (k).

Необходимо ещё раз внимательно посмотреть на один из ВАЖНЫХ МОМЕНТОВ в условии задачи:

Важный момент из условия задачи. Диапазон значений для переменной (k).
Важный момент из условия задачи. Диапазон значений для переменной (k).

→ В условии задачи для переменной k задан определённый диапазон значений.

Это значит, что переменная k должная поочередно принимать значения из заданного диапазона:

k = 1 000 000 000, 1 000 000 001, 1 000 000 002, ... 2 000 000 000.

  • Можно ли не использовать циклы for / while?

— Да!

В таком случае, для каждого значения k потребуется вручную вызвать функцию F и проверить результат работы функции:

Проверка результата работы функции ручным методом для каждого значения перепенной (k).
Проверка результата работы функции ручным методом для каждого значения перепенной (k).

F(1 000 000 000) - ?

...

F(2 000 000 000) - ?

❗ЭТО МИЛЛИАРД ВАРИАНТОВ 😳

☑ Цикл for (while) позволяет автоматизировать данный процесс.

→ Для проверки работы цикла for можно изменить диапазон в range и вызвать функцию F:

range(10 ** 9, 2 * 10 ** 9)range(10 ** 9, 10 ** 9 + 5)

Изменение диапазона в (range) для промежуточной проверки работы алгоритма.
Изменение диапазона в (range) для промежуточной проверки работы алгоритма.

F(k) — многократный вызов функции (F) с аргументом (k).

end = ' ' — вывод значений на экран в одну строчку.

0 — значение функции F при k = 1 000 000 000.

4 — значение функции F при k = 1 000 000 004.

🔥 ПЕРЕХОДИМ К ЗАКЛЮЧИТЕЛЬНОМУ ЭТАПУ ↓

🔹 ВЫВОД РЕЗУЛЬТАТА НА ЭКРАН

С помощью функции print() и переменной b

По условию задачи необходимо определить количество целых k, для которых выполняется данное соотношение:

  • F(k) = 2
-17

→ Чтобы перенести условие из задачи в код Python, необходимо воспользоваться оператором if:

if — команда, которая позволяет программе принимать определённые решения.

Условие необходимо записать внутри цикла for, где выполняется подстановка различных значений для k:

🚀 КОД ПРОГРАММЫ (ИТОГОВОЕ РЕШЕНИЕ):

Итоговое решение.
Итоговое решение.

Алгоритм запущен, но ответ пока не отображается ...

  • Что это значит?
-19

Если код программы написан верно, ошибок нет, то это может означать лишь одно:

❌ ПРОГРАММА БУДЕТ ВЫПОЛНЯТСЯ ПРОДОЛЖИТЕЛЬНОЕ ВРЕМЯ!

И если подождать какое - то количество времени, то ответ всё же появится:

Итоговое решение + ответ к задаче.
Итоговое решение + ответ к задаче.
Ответ: 15116545.

⭐ Good Job! But ...

— Ответ получен, программа работает. Решение верное. Но как быть с длительным ожиданием завершения программы? Можно ли как то ускорить выполнение алгоритма?

На все эти вопросы попробуем ответить в следующей главе →

АНАЛИЗ РЕШЕНИЯ

Необходимо разобрать во всех нюансах полученного решения ⤵

В первую очередь попробуем узнать, сколько времени выполнялась программа. Для измерения времени работы программы в Python существует специальный модуль ↓

📌 import time

-21

import time — инструмент для работы со временем в Python.

time.process_time() — команда для фиксации временного промежутка (start → stop).

Добавим модуль time в полученное решение и измерим время работы программы ↓

Измерение времени работы программы в Python с помощью модуля (time).
Измерение времени работы программы в Python с помощью модуля (time).

Общая схема работы с модулем time:

  1. Подключить модуль time.
  2. Отметить время начала программы: start = time.process_time().
  3. Отметить завершение программы: end = time.process_time().
  4. Вывести на экран разницу между временем завершения и временем начала: end - start.
-23

И после запуска программы итоговое время получится:

-24
Время выполнения программы = 13 минут (784 секунды).

❕ВАЖНЫЙ МОМЕНТ:

Время выполнения программы может различаться в зависимости от устройства. Чем выше производительность оборудования, тем быстрее будет работать программа.

📥 Попробуйте выполнить программу на своём устройстве и напишите в комментариях, какое время работы получилось у вас.

Время работы программы = 13 минут. Это МНОГО или МАЛО?

Для ответа на этот вопрос попробуем измерить время работы другой программы 👉

📌 ПРИМЕР ДЛЯ СРАВНЕНИЯ

Рассмотрим решение знакомой задачи из предыдущего материала ⤵

  • УСЛОВИЕ ЗАДАЧИ:
Условие задачи.
Условие задачи.

Воспользуемся модулем time для измерения времени работы программы:

  • РЕШЕНИЕ + import time
Решение задачи на рекурсивную функцию из предыдущих статей с использованием модуля (time).
Решение задачи на рекурсивную функцию из предыдущих статей с использованием модуля (time).

📍В решении используется сразу же два модуля sys и time. Модули можно записать в один import.

  • После запуска программы на экране появляется такое число:
Время выполнения алгоритма в Python.
Время выполнения алгоритма в Python.

😳😳😳

13 минут vs 0,000006 секунд

ПОЧЕМУ ПОЛУЧИЛАСЬ ТАКАЯ БОЛЬШАЯ РАЗНИЦА

Для ответа на этот вопрос необходимо вернуться к условию исходной задачи 👉

ОЦЕНКА ДИАПАЗОНА

Для определения времени работы программы ⤵

-28

Как было отмечено выше ⇪ в данной задаче для переменной k задан определённый диапазон значений:

от 1 000 000 000 → до 2 000 000 000

❌ И ЭТО ОЧЕНЬ БОЛЬШОЙ ДИАПАЗОН ДЛЯ РАБОТЫ РЕКУРСИВНОЙ ФУНКЦИИ В PYTHON

Программа должна будет выполнить минимум 1 МИЛЛИАРД операций. При использовании рекурсивной функции количество операций будет ещё больше.

Как оценить время выполнения программы по заданному диапазону из условия? Ответ на вопрос в следующей главе →

🕒 ОЦЕНКА ВРЕМЕНИ РАБОТЫ ПРОГРАММЫ

В зависимости от времени выполнения одного вызова ⤵

➀ t = 0,00001

-29

→ Предположим, что на выполнение одного рекурсивного вызова требуется 0,00001 секунды.

Тогда для выполнения 1 миллиарда операций (1 000 000 000) потребуется:

  1. 1 000 000 000 * 0,00001 = 10 000 секунд
  2. 10 000 : 60 = 166 минут
166 минут — примерное время выполнения программы при обработке 1 миллиарда входных значений.

➁ t = 0,000001

-30

→ Предположим, что на выполнение одного рекурсивного вызова потребуется уже 0,000001 секунды.

Тогда для выполнения того же миллиарда операций потребуется:

  1. 1 000 000 000 * 0,000001 = 1 000 секунд
  2. 1 000 : 60 = 16,6 минут
16,6 — это приблизительно тот результат, который возвращает текущее решение.

На основании полученных значений времени 166 минут и 16,6 минуты, возникает логичный вопрос:

КАК СОКРАТИТЬ ВРЕМЯ РАБОТЫ ПРОГРАММЫ?

Ответ:

— Оптимизировать решение

🎯 ОПТИМИЗАЦИЯ РЕШЕНИЯ

3 способа, которые могут увеличить скорость выполнения алгоритма

  • ИТЕРАТИВНЫЙ МЕТОД
-31

→ Реализовать решение задачи без рекурсивного алгоритма. Вместо многократных вызовов функции её значения будут последовательно записываться в список (list).

  • АНАЛИТИЧЕСКОЕ РЕШЕНИЕ
-32

БЕЗ СОЗДАНИЯ ПРОГРАММЫ НА PYTHON

Для записи решения можно использовать тетрадь или Paint.

  • Основная задача — поиск закономерностей.

Следует внимательно изучить принцип работы алгоритма. Разложить на составляющие. Протестировать алгоритм на нескольких примерах. Затем, опираясь на полученные данные, вывести общее решение и выполнить необходимые расчёты.

  • АВТОРСКОЕ РЕШЕНИЕ

→ Комбинация двух предыдущих подходов: написать код, который точно реализует необходимый алгоритм и при этом будет работать максимально быстро. Допускается использование любых методов, модулей и инструментов.

👉 ПЕРВЫЙ СПОСОБ ОПТИМИЗАЦИИ АЛГОРИТМА →

📍РЕШЕНИЕ ИТЕРАТИВНЫМ МЕТОДОМ

Подход к решению задач через повторяющиеся циклы вместо повторяющихся рекурсивных вызовов ⤵

Необходимо ещё раз внимательно посмотреть на условие задачи перед написанием кода в Python:

Условие задачи.
Условие задачи.

🚀 РЕШЕНИЕ ЗАДАЧИ ИТЕРАТИВНЫМ МЕТОДОМ (1 вариант):

❕ВАЖНЫЙ МОМЕНТ:

При заполнении списка (a) внутри цикла (for) можно сразу проверять условие F(k) = 2 и подсчитывать подходящие варианты. Это позволит не запускать второй цикл (for) и не перебирать каждый элемент заново ↓

Решение задачи на рекурсивную функцию с помощью итеративного метода.
Решение задачи на рекурсивную функцию с помощью итеративного метода.

a — список (list) для хранения всех значений рекурсивной функции (F).

a.append() — добавление новых элементов в конец списка.

b — переменная для подсчёта подходящих вариантов.

if a[k] — поиск подходящих вариантов при F(k) = 2.

  • После запуска программы появится ответ и время работы алгоритма:

Время выполнения алгоритма ≈ 272 секунды.

👏 Better, even better!

Сравнение времени работы программы итеративным методом и через рекурсивную функцию.
Сравнение времени работы программы итеративным методом и через рекурсивную функцию.

🔥 С ПОМОЩЬЮ ИТЕРАТИВНОГО МЕТОДА УДАЛОСЬ УМЕНЬШИТЬ ВРЕМЯ РАБОТЫ ПРОГРАММЫ ПРАКТИЧЕСКИ В 4 РАЗА! ОЧЕНЬ ХОРОШО! 😉

Попробуем записать базовый случай рекурсии сразу же в список, чтобы программа каждый раз не тратила время на проверку дополнительного условия ↓

✖ if k == 0

Для уменьшения времени работы алгоритма, базовый случай рекурсии можно записать сразу же в исходный список.
Для уменьшения времени работы алгоритма, базовый случай рекурсии можно записать сразу же в исходный список.

🚀 РЕШЕНИЕ ЗАДАЧИ ИТЕРАТИВНЫМ МЕТОДОМ (2 вариант):

-37

После запуска программы появится ответ и время работы алгоритма:

Время выполнения алгоритма ≈ 254 секунды.

ОТЛИЧНО! РЕЗУЛЬТАТ ЕЩЁ ЛУЧШЕ 😉

271 секунда → 254 секунды

-38

  • ПРОМЕЖУТОЧНЫЕ ИТОГИ:

С помощью итеративного подхода удалось сократить время выполнения алгоритма с 784 секунд (рекурсия) до 254 секунд. Разница существенна!

НО

Как было отмечено ⇪ выше, скорость выполнения программы также зависит и от мощности процессора: частота, архитектура и число быстрых ядер. Поэтому программа будет работать дольше (порой значительно) на менее мощных процессорах.

👉 ПЕРЕХОДИМ КО ВТОРОМУ СПОСОБУ ОПТИМИЗАЦИИ РЕШЕНИЯ →

📍АНАЛИТИЧЕСКОЕ РЕШЕНИЕ

С использованием комбинаторики и логического мышления ⤵

⚠ Чтобы решить задачу аналитическим / математическим способом, прежде всего необходимо разобрать и понять принцип работы алгоритма.

PYTHON vs РАССУЖДЕНИЯ

Необходимо составить таблицу по переводу алгоритма в математические действия ⤵

Таблица соответствия команд из условия задачи и математических рассуждений:

-39

Следующий этап — взять несколько значений для переменной (k) и прогнать через алгоритм. Для того, чтобы на частных случаях понять общий ход решения.

  • Какие лучше брать числа?

— Все возможные случаи: Чётные и нечётные / Двузначные, трёхзначные, возможно и четырёхзначные / Содержащие как чётные так и нечётные цифры.

Запись промежуточных результатов можно выполнять на листке, в Paint или в самом Python.

→ k = 33

Первое число для работы с алгоритмом ⤵

-40

После подставления числа 33 рекурсия вызовет функцию F(3), поэтому необходимо применить алгоритм уже к числу 3 ↓

-41

После вызова функции F(3) рекурсивная функция вызовет функцию F(0), поэтому необходимо применить алгоритм уже к числу 0 ↓

-42

0 базовый случай рекурсивной функции, поэтому здесь функция вернёт значение 0.

После этого алгоритм закончит свою работу с числом k = 33.

-43
Промежуточный результат:

Если k = 33, алгоритм вернёт число 0. Пока никакой закономерности не прослеживается, поэтому необходимо взять следующее число

→ k = 125

Второе число для работы с алгоритмом ⤵

-44

После подставления числа 125 рекурсия вызовет функцию F(12), поэтому необходимо применить алгоритм уже к числу 12 ↓

-45

После подставления числа 12 рекурсия вызовет функцию F(1), поэтому необходимо применить алгоритм уже к числу 1 ↓

-46

После вызова функции F(1) рекурсивная функция вызовет функцию F(0), поэтому необходимо применить алгоритм уже к числу 0 ↓

-47

0 базовый случай рекурсивной функции, поэтому здесь функция вернёт значение 0.

После этого алгоритм закончит свою работу с числом k = 125.

-48
Промежуточный результат:

Если k = 125, алгоритм вернёт число 2. Попробуем взять следующее число

→ k = 4856

Третье число для работы с алгоритмом ⤵

-49

После подставления числа 4856 рекурсия вызовет функцию F(485), поэтому необходимо применить алгоритм уже к числу 485 ↓

-50

После подставления числа 485 рекурсия вызовет функцию F(48), поэтому необходимо применить алгоритм уже к числу 48 ↓

-51

После подставления числа 48 рекурсия вызовет функцию F(4), поэтому необходимо применить алгоритм уже к числу 4 ↓

-52

После подставления числа 4 рекурсия вызовет функцию F(0), поэтому необходимо применить алгоритм уже к числу 0 ↓

-53

0 базовый случай рекурсивной функции, поэтому здесь функция вернёт значение 0.

После этого алгоритм закончит свою работу с числом k = 4856.

-54

🔥Вот оно! Закономерность найдена!

ЗАКОНОМЕРНОСТЬ

Необходимо внимательно посмотреть на исходные числа и результат работы алгоритма ⤵

  • Если в исходном числе отсутствуют чётные цифры, результат будет равен 0, как это произошло в случае с числом 33.
  • Как только в исходном числе появляются чётные цифры, алгоритм возвращает уже не 0, а сумму этих чётных цифр.
-55

❗АЛГОРИТМ ПОДСЧИТЫВАЕТ СУММУ ЧЁТНЫХ ЦИФР В ЗАДАННОМ ЧИСЛЕ

Для подтверждения теории можно запустить готовую программу в Python с заданными значениями для k ↓

-56
  • k = 1246 → a[1246] = 2 + 4 + 6 = 12
  • k = 100 → a[100] = 0
  • k = 259 → a[259] = 2

✅ Закономерность выполняется.

И ещё несколько значений + время выполнения программы ↓

-57
  • k = 3333 → a[3333] = 0
  • k = 2224 → a[2224] = 2 + 2 + 2 + 4 = 10
  • k = 1234567 → a[1234567] = 2 + 4 + 6 = 12

Закономерность найдена. Как теперь прийти к ответу?

По условию задачи необходимо найти такие значения k, для которых F(k) = 2.

Если функция F(k) возвращает сумму чётных цифр заданного числа k, то это будет означать, что:

❗НЕОБХОДИМО НАЙТИ ВСЕ ЧИСЛА ИЗ ЗАДАННОГО ДИАПАЗОНА ДЛЯ КОТОРЫХ СУММА ЧЁТНЫХ ЦИФР РАВНА 2

Для подтверждения полученной теории можно воспользоваться готовой программой на Python. Проверим, какие значения принимает функция F при различных значениях k и выполнении условия F(k) = 2

  • 1 программа диапазон чисел от 1 до 29:

2, 12, 20, 21, 23, 25, 27, 29 — у всех чисел сумма чётных цифр равняется 2.

  • 2 программа диапазон чисел от 100 до 129:

102, 112, 120, 121, 123, 125, 127, 129 — у всех чисел сумма чётных цифр равняется 2.

  • 3 программа диапазон чисел от 1000 до 1029:

1002, 1012, 1020, 1021, 1023, 1025, 1027, 1029 — у всех чисел сумма чётных цифр равняется 2.

Во всех рассмотренных случаях алгоритм возвращает числа, в которых сумма чётных цифр равна 2. Иными словами, это числа, содержащие единственную чётную цифру — 2.

КАК ПОДСЧИТАТЬ КОЛИЧЕСТВО ТАКИХ ЧИСЕЛ?

— Разобрать все возможные случаи расположения цифры 2 ⤵

Необходимо вновь внимательно рассмотреть заданный диапазон для переменной k

Диапазон значений, которые может принимать переменная (k).
Диапазон значений, которые может принимать переменная (k).

❗ОСНОВНЫЕ ПРАВИЛА ПОДБОРА ЧИСЕЛ:

  • Число может содержать только одну чётную цифру больше нуля — 2.
  • Все остальные цифры могут быть либо нечётными (1, 3, 5, 7, 9), либо 0.
  • Число всегда будет начинаться с цифры 1, кроме (2 000 000 000).

Несколько примеров подходящих чисел:

Примеры чисел из заданного диапазона, которые соответствуют установленному правилу.
Примеры чисел из заданного диапазона, которые соответствуют установленному правилу.

Если зафиксировать цифру 2 на одной позиции (например, в последнем разряде), то можно подсчитать количество способов размещения остальных цифр: 0, 1, 3, 5, 7 и 9.

После перемножения количества вариантов для каждой позиции получим общее число вариантов при данном расположении цифры 2.

ЦИФРА 2 НА ПОСЛЕДНЕМ МЕСТЕ

-61

На первом месте будет расположена цифра 1, так как задан диапазон чисел от 1 000 000 000 до 2 000 000 000. На последнем месте цифра 2. На всех остальных позициях может расположится одна из 6 цифр: 0, 1, 3, 5, 7, 9.

→ Для подсчёта всех возможных чисел нужно перемножить количество доступных цифр на каждой позиции:

1 · 6 · 6 · 6 · 6 · 6 · 6 · 6 · 6 · 1 = 1 679 616

Получается всего 1 679 616 чисел, в которых на первом месте стоит цифра 1, на последнем месте цифра 2 и все остальные цифры это 0, 1, 3, 5, 7, 9.

ЦИФРА 2 НА ПРЕДПОСЛЕДНЕМ МЕСТЕ

-62

На первом месте вновь будет расположена цифра 1. На предпоследнем месте цифра 2. На всех остальных позициях вновь одна из 6 цифр: 0, 1, 3, 5, 7, 9.

→ Для подсчёта всех возможных чисел нужно перемножить количество доступных цифр на каждой позиции:

1 · 6 · 6 · 6 · 6 · 6 · 6 · 6 · 1 · 6 = 1 679 616

Вновь, получается всего 1 679 616 чисел, в которых на первом месте стоит цифра 1, на предпоследнем месте цифра 2 и все остальные цифры это 0, 1, 3, 5, 7, 9.

Общая закономерность:

ВО ВСЕХ СЛУЧАЯХ КОЛИЧЕСТВО ВАРИАНТОВ ЧИСЕЛ ОСТАЁТСЯ НЕИЗМЕННЫМ, МЕНЯЕТСЯ ЛИШЬ ПОЗИЦИЯ ЦИФРЫ 2 В КАЖДОМ ЧИСЛЕ.

Все возможные варианты расположения цифры 2.
Все возможные варианты расположения цифры 2.

Следовательно, можно определить общее количество возможных вариантов ↓

Нахождение общего количества чисел при заданных условиях.
Нахождение общего количества чисел при заданных условиях.
15 116 544 — количество чисел у которых на первом месте цифра 1, всего одна цифра 2 и все остальные цифры это 0, 1, 3, 5, 7, 9.

Осталось сверить полученный результат с полученным ответом из Python

-65

❗ОТВЕТЫ НЕ СОВПАДАЮТ

Ответ, полученный аналитическим способом, отличается от ответа из Python.

  • Почему так получилось?

➕НЕОБХОДИМО ЗАПИСАТЬ ЕЩЁ ОДИН ВАРИАНТ

Существует ещё одно число в котором только одна чётная цифра 2, а остальными цифрами могут быть 0, 1, 3, 5, 7, 9

→ И это число 2 000 000 000

Число 2 000 000 000 также необходимо включить в итоговый ответ.
Число 2 000 000 000 также необходимо включить в итоговый ответ.
  • k = 2 000 000 000 — удовлетворяет всем заданным условиям и входит в допустимый диапазон для переменной k.

→ Следовательно:

15 116 544 + 1 = 15 116 545

Ответ: 15 116 545.

⭐ Good Job!

🔥 АВТОРСКОЕ РЕШЕНИЕ В СЛЕДУЮЩЕЙ ЧАСТИ →

-67