Задание 23

Исполнитель преобразует число на экране.
У исполнителя есть три команды, которые обозначены латинскими буквами:
A. Прибавить 1
B. Умножить на 2
B. Возвести в квадрат
Программа для исполнителя – это последовательность команд.
Сколько существует программ, для которых при исходном числе 2 результатом является число 20 и при этом траектория вычислений не содержит число 11?
Траектория вычислений программы – это последовательность результатов выполнения всех команд программы. Например, для программы CBA при исходном числе 4 траектория состоит из чисел 16, 32, 33.

Теория

Задание на анализ и выполнение алгоритма. Необходимо подсчитать количество различных траекторий (путей, или программ), которые приводят из исходного числа к конечному. Возможны дополнительные условия, что траектория содержит одно или несколько чисел и не содержит другое. Решается данная задача аналитически или с помощью компьютера, например в MSExcel или программированием с использованием рекурсивного алгоритма. Решение графическим построением дерева траекторий слишком трудоемкое и долгое.

Решение

Аналитический способ

Решение с помощью Excel (возможно и на черновике вручную). Выполним анализ команд (+1, *2 и возведение в квадрат **2) и построим таблицу в Excel с помощью автозаполнения, приведенную на рисунке ниже

23 задание демо 24 таблица

Алгоритм простой. В строке 1 - числа, которые получаются при старте с 2 и выполнении команд +1, *2 и **2.  Строка 2 таблицы содержит количество способов попасть в ячейку с числом выше. Стартуем с 2 - ставим 1 способ. Далее для всех нечетных чисел просто - в них можно попасть только из предыдущего (на 1 меньше) числа, прибавив к нему 1. Исключение число 9 - в него можно попасть 8+1, а также 3**2 - суммируем способы соответственно чисел 3 и 8 (7+1) и получаем 8. В число 4 можно попасть тремя способами (3+1, 2*2, 2**2) - три раза суммируем способы числа 2. Рекомендация снизу писать все способы для каждого числа, чтобы не ошибиться. Число 11 - оранжевая ячейка - ее минуем!
Весь алгоритм заключается в суммировании количества способов тех чисел, из которых можно попасть в данное число и запись этой суммы под числом во второй строке. Например в число 6 можно с помощью наших команд попасть из 15 (15+1), 8 (8*2) и 4 (4**2). Суммируя C2+G2+N2 получаем 18. Для числа 20 результат будет 37.

Программа

1-й способ

Без рекурсии со списком - эмуляция алгоритма изложенного выше в Excel.

n = []
for k in range (0,21):
    n.append(0)
n[2] = 1
print(n)#исходный список нулей
for k in range(3,21):
    if k%2==1:
        if k!=11:
            n[k]=n[k-1]
    else:
        n[k]=n[k-1]+n[k//2]
    if k**0.5%1 == 0:
        n[k]=n[k]+n[int(k**0.5)]
print(n)#итоговый список 
print(n[20])

2-й способ

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

def F(k):
    res = 0
    if k==2: res=1
    elif k<2 or k==11: res=0
    else:
        if k**0.5%1 != 0:
            if k%2==1:
                res=F(k-1)
            else:
                res=F(k-1)+F(k//2)
        else:
            if k%2==1:
                res=F(k-1)+F(int(k**0.5))
            else:
                res=F(k-1)+F(k//2)+F(int(k**0.5))
    return res
for k in range(2,21):
  print(k,'-',F(k))

Ответ

37 (Время не более 10 минут)

Яндекс.Метрика