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

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

Задача 1#30478

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

1. Поделить на 2, если число четное

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

3. Прибавить треть числа, если число кратно трем

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

Сколько существует программ, для которых при исходном числe 1 результатом является число 60, при этом программа содержит 25 команд, при этом одно и то же число может встречаться несколько раз в траектории вычислений исполнителя.

Траектория вычислений — это последовательность результатов выполнения всех команд программы. Например, для программы 12223 при исходном числе 6 траектория будет состоять из чисел 3, 4, 5, 6, 8.

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

Решение 1 (Рекурсия)

from functools import lru_cache  # программа будет долго считать, если
# не хранить результаты в кэше
@lru_cache(None)
def f(st, fn, count, end_count):
    if st == fn and count == end_count:
        return 1
    if count > end_count:
        return 0
    x = f(st // 2, fn, count + 1, end_count) * (st % 2 == 0)
    y = f(st + 1, fn, count + 1, end_count)
    z = f(st + st // 3, fn, count + 1, end_count) * (st % 3 == 0)
    return x + y + z


print(f(1, 60, 0, 25))

Решение 2 (Динамика)

ans = []
ans.append(1)
for operations in range(25):
    can_get = []
    for i in ans:
        if i % 2 == 0:
            can_get.append(i // 2)
        can_get.append(i + 1)
        if i % 3 == 0:
            can_get.append(i + i // 3)
    ans = can_get
print(ans.count(60))

Ответ: 386

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

Задача 2#30477

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

1. Поделить на 2, если число четное

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

3. Прибавить треть числа, если число кратно трем

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

Сколько существует программ, для которых при исходном числe 1 результатом является число 60, при этом программа содержит 25 команд, при этом одно и то же число не может встречаться несколько раз в траектории вычислений исполнителя. Исполнителю также нельзя посещать начальное значение.

Траектория вычислений — это последовательность результатов выполнения всех команд программы. Например, для программы 122 при исходном числе 6 траектория будет состоять из чисел 3, 4, 5.

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

Решение 1

def f(st, fn, cmd, a):
    if st in a or cmd > 25:
        return 0
    if st == fn and cmd == 25:
        return 1
    a.add(st)
    x, y, z = 0, 0, 0
    if st % 2 == 0:
        x = f(st // 2, fn, cmd + 1, a.copy())
    y = f(st + 1, fn, cmd + 1, a.copy())
    if st % 3 == 0:
        z = f(st + st // 3, fn, cmd + 1, a.copy())
    return x + y + z

Решение 2

В соавторстве с марафонцем

Примечание: при добавлении в массив b элементов массива a используется символ *, чтобы добавить в массив именно элементы массива а, а не создать дополнительную вложенность массивов. Например: есть массив a = [1, 2, 3]. Если выполнить операцию b.append([a, 4]), то массив b = [[[1, 2, 3], 4]]. Если выполнить b.append([*a, 4]), то массив b = [[1, 2, 3, 4]].

paths = [[1]]
for i in range(25):
    new_paths = []

    for path in paths:
        x = path[-1]
        if x % 2 == 0:
            if x // 2 not in path:
                new_paths.append([*path, x//2])
        if x % 3 == 0:
            if x + x // 3 not in path:
                new_paths.append([*path, x + x//3])
        if x + 1 not in path:
            new_paths.append([*path, x+1])
    paths = new_paths.copy()

ans = 0
k = []
for path in paths:
    if path[-1] == 60:
        k.append(path)
        ans += 1
print(ans)

 

Ответ: 32

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

Задача 3#30476

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

1. Вычесть 3

2. Вычесть 1

3. Поделить на 2  , если число четное

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

Сколько существует программ, для которых при исходном числe 33  результатом является число 12  , при этом программа содержит 9  команд?

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

Решение 1 (Рекурсия)

def f(st, fn, count, end_count):
    if st == fn and count == end_count:
        return 1
    if st < fn or count > end_count: # если счетчик перешел максимальное
# значение, то прекращаем считать
        return 0
    x = f(st // 2, fn, count + 1, end_count) * (st % 2 == 0)
    y = f(st - 3, fn, count + 1, end_count)
    z = f(st - 1, fn, count + 1, end_count)
    return x + y + z
print(f(33, 12, 0, 9))

Решение 2 (Динамика)

a = [33]
for i in range(9):
    n = len(a)
    for j in range(n):
        k = a.pop(0)
        if k > 12:
            a.append((k // 2) * (k % 2 == 0))
            a.append(k - 3)
            a.append(k - 1)
print(a.count(12))

Ответ: 85

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

Задача 4#11538

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

  1. Удвоить
  2. Удвоить и прибавить 1
  3. Утроить и прибавить 1

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

Программа для исполнителя ДЮ — это последовательность команд. Сколько различных результатов можно получить из исходного числа 1  после выполнения программы, содержащей ровно 7  команд?

Показать ответ и решение
# set может хранить только по одному экземпляру каждого числа,
# то есть все числа внутри будут различными
a = set()
# каждая последовательность команд будет содержать 7 команд
# последовательность команд состоит из чисел 1 2 3
# в алфавите 3СС тоже три числа
# необходимо рассмотреть все семиразрядные числа в 3СС
# каждая из них будет представлять последовательность команд
for i in range(3**7):
    t = i # какая-то последовательность команды (в 10СС)
    n = 1 # тут хранится результат работы данной последовательности
    # перевод последовательности команд в 3СС
    # мы сами переназвали команды, теперь *2 это 0-вая команда и тд
    for j in range(7):
        if t % 3 == 0:
            n*=2
        if t%3==1:
            n = n*2 +1
        if t%3==2:
            n = n*3 + 1
        t //= 3
    # добавляем число в множество, если оно там уже есть,
    # то ничего не произойдет
    a.add(n)
print(len(a))

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