Тема 23. Оператор присваивания и ветвления

23.08 Прочие прототипы

Вспоминай формулы по каждой теме
Решай новые задачи каждый день
Вдумчиво разбирай решения
ШКОЛКОВО.
Готовиться с нами - ЛЕГКО!
Подтемы раздела оператор присваивания и ветвления
Решаем задачу:

Ошибка.
Попробуйте повторить позже

Задача 1#84013

Исполнитель преобразует число на экране. У исполнителя есть пять команд, которым присвоены номера:

1. Увеличь на разряд единиц

2. Увеличь на разряд десятков

3. Умножь на разряд единиц

4. Умножь на разряд десятков

5. Прибавь 1

Первая и третья команды используют значение разряда единиц числа (например у 13 это 3, а у 28 - 8), а вторая и четвертая команды используют значение разряда десятков числа (например у 81 это 8, а у 35 это 3). Причём не разрешается выполнять команду, если после неё число на экране не изменится, либо превратится в 0. Программа для исполнителя – это последовательность команд.

Сколько существует программ, для которых при исходном числе 25 результатом является число 111, если известно, что нельзя повторять команду, сделанную два шага назад (например программа 112 допустима, а 121 - нет)?

Показать ответ и решение

Решение рекурсией

Мы будем использовать рекурсивный метод для подсчета всех допустимых программ. Введем функцию f(a, b, c1, c2), где:

- a  — текущее число на экране,

- b  — целевое число,

- c1  — номер команды, использованной на предыдущем шаге,

- c2  — номер команды, использованной два шага назад.

На каждом шаге проверяем условия:

- если a > b  , дальнейшее выполнение команд невозможно, возвращаем 0  ;

- если a == b  , значит достигнут результат, возвращаем 1  .

Далее вычисляем единицы и десятки числа a  :

- x = a%10  — цифра единиц,

- y = a∕∕10%10  — цифра десятков.

Для каждой команды проверяем:

- Если команда не была выполнена два шага назад (c2 != номер команды) и применение команды изменит число и не приведет к 0, то рекурсивно вызываем функцию с новым значением числа и обновленными c1  и c2  .

- Суммируем результаты всех возможных рекурсивных вызовов.

Функция кешируется с помощью lru_cache, чтобы ускорить вычисления за счет запоминания ранее вычисленных значений. Вызов f(25, 111) вернет количество всех допустимых программ.

# Импортируем кеширование для ускорения рекурсии
from functools import lru_cache

# Определяем рекурсивную функцию f(a, b, c1, c2)
# a - текущее число, b - целевое число
# c1 - предыдущая команда, c2 - команда два шага назад
@lru_cache(None)
def f(a, b, c1 = 0, c2 = 0):
    # Если текущее число больше целевого, путь невозможен
    if a > b:
        return 0
    # Если текущее число равно целевому, найден допустимый путь
    if a == b:
        return 1
    # Инициализируем счетчик программ на этом шаге
    s = 0
    # Определяем цифру единиц числа a
    x = a % 10
    # Определяем цифру десятков числа a
    y = a // 10 % 10

    # Команда 1: прибавить разряд единиц
    if c2 != 1 and x != 0:
        s += f(a + x, b, 1, c1)

    # Команда 2: прибавить разряд десятков
    if c2 != 2 and y != 0:
        s += f(a + y, b, 2, c1)

    # Команда 3: умножить на разряд единиц
    if c2 != 3 and x != 0 and x != 1:
        s += f(a * x, b, 3, c1)

    # Команда 4: умножить на разряд десятков
    if c2 != 4 and y != 0 and y != 1:
        s += f(a * y, b, 4, c1)

    # Команда 5: прибавить 1
    if c2 != 5:
        s += f(a + 1, b, 5, c1)

    # Возвращаем суммарное количество программ с этого шага
                                                                                                  
                                                                                                  
    return s

# Вычисляем и выводим количество программ от 25 до 111
print(f(25, 111))

Ответ: 3548990

Специальные программы

Все специальные программы

Программа
лояльности v2.0

Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!

Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.

Бесплатное онлайн-обучение

Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.

Налоговые вычеты

Узнай, как получить налоговый вычет при оплате обучения в «Школково».

Специальное предложение
для учителей

Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!

Вернём деньги за курс
за твою сотку на ЕГЭ

Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!

cyberpunkMouse
cyberpunkMouse
Рулетка
Вы можете получить скидку в рулетке!