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

23.05 Количество программ из A в B смешанное

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

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

Задача 1#26183

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

1. Прибавить 1

2. Умножить на 2

Первая команда увеличивает число на экране на 1, вторая умножает его на 2.

Программа для исполнителя – это последовательность команд.

Сколько существует программ, для которых при исходном числе 3 результатом является число 45 и при этом траектория вычислений содержит число 10 и не содержит число 15?

Ответ дайте в шестеричной системе счисления

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

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

Мы используем рекурсивный подход для подсчета количества программ. Основная идея: создаем функцию, которая считает количество программ, преобразующих число x  в число y  , учитывая ограничения на числа, которые нельзя проходить. В функции проверяем следующие условия:

1. Если текущее число x  больше целевого числа y  или равно запрещенному числу (в данном случае 7), то путь невозможен, возвращаем 0.

2. Если текущее число x  совпало с целевым y  , значит найден один корректный путь, возвращаем 1.

3. Если текущее число меньше целевого, то функция вызывает саму себя для каждого возможного действия:

- прибавить 1 к числу,

- прибавить 3 к числу,

- умножить число на 4 (в оригинальном коде для упрощения использовано прибавление и удвоение, адаптируем под условие).

Мы разделяем вычисление на два этапа: от начального числа 3 до промежуточного 12 и от 12 до конечного 20. Количество программ на каждом этапе подсчитывается рекурсивно. Итоговое количество программ вычисляется как произведение числа способов для первой и второй части, так как каждый путь из первой части можно соединить с любым путем второй части.

# Функция для перевода числа в шестнадцатеричную или другую систему счисления
def perevod(n):
    # Инициализируем пустую строку для хранения результата
    s = ’’
    # Пока число не равно 0
    while n != 0:
        # Получаем остаток от деления на 6 и добавляем к строке слева
        s = str(n % 6) + s
        # Делим число на 6 целочисленно
        n //= 6
    # Возвращаем строковое представление числа
    return s

# Рекурсивная функция для подсчета количества программ
def f(x,y):
    # Если текущее число больше целевого или равно запрещенному 15,
    # путь невозможен
    if x > y  or x == 15:
        return 0
    # Если текущее число совпало с целевым, найден один путь
    if x == y:
        return 1
    # Иначе считаем количество программ для каждого действия
    if x < y:
        # прибавляем 1 или умножаем на 2 (по сути прибавление 3 реализуется аналогично)
        return f(x + 1, y) + f(x * 2, y)

# Вычисляем произведение количества программ на двух этапах
# от 3 до 10 (соответствует 12) и от 10 до 45 (соответствует 20)
print(perevod(f(3, 10) * f(10, 45)))

Решение динамикой

Мы используем динамическое программирование для подсчета количества программ. Создаем массив, где индекс соответствует числу на экране, а значение — количеству способов достичь этого числа. Сначала заполняем массив нулями и устанавливаем значение для начального числа 3 как 1, так как изначально мы находимся в этом числе. Далее перебираем все числа от 4 до 45 и обновляем количество способов для каждого числа:

- прибавляем количество способов попасть из i− 1  ,

- если число делится на 2, прибавляем количество способов попасть из i∕∕2  ,

- если число равно запрещенному 15, обнуляем значение,

- если число равно промежуточному 10 (соответствует 12), обнуляем все предыдущие ячейки, чтобы исключить траектории, не проходящие через 12.

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

# Функция для перевода числа в систему счисления с основанием a
def perevod(n, a):
    # Инициализируем пустую строку
    s = ’’
    # Пока число не равно 0
    while n != 0:
        # Получаем остаток от деления на a и добавляем к строке слева
        s = str(n % a) + s
        # Делим число на a целочисленно
        n //= a
    # Возвращаем строковое представление числа
    return s

# Создаем массив для хранения количества программ
a = [0]*46
# Устанавливаем начальное число 3 как 1
a[3] = 1
# Перебираем числа от 4 до 45
for i in range(4, 46):
    # Любое число можно получить прибавлением 1 к предыдущему
    a[i] = a[i-1]
    # Если число делится на 2, можно попасть из i//2
    if i % 2 == 0:
        a[i] += a[i//2]
    # Если число равно запрещенному 15, путь невозможен
    if i == 15:
        a[i] = 0
    # Если число равно промежуточному 10, обнуляем все предыдущие пути
    if i == 10:
        for j in range(i):
            a[j] = 0
# Выводим количество программ в шестиричной системе
print(perevod(a[45], 6))

Ответ: 100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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