Задача к ЕГЭ по информатике на тему «Теория игр» №5

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

В ответе запишите числа в порядке возрастания без пробелов и знаков препинания.

Решение руками

После небольшого перебора выясняем, что нам подходят значения S = 46,85,92.  В каждой из этих позиций есть ход, ведущий Петю в позицию выигрыша Вани первым ходом: при первом значении Петя умножит первую кучу на 2  , при втором увеличит первую кучу на 1  , а при третьем значении увеличит вторую кучу на 1  . Значит они нам подходят.

Решение БУ

from functools import lru_cache

@lru_cache(None)
def game(first_heap, second_heap,count_moves):  # Функция игры.
    # count_moves это счётчик ходов в партии, его мы добавили для того чтобы избежать ошибки превышения лимита рекурсии.
    # Это работает следующим образом: если в партии больше 6 ходов, то есть по три хода Пети и Вани, а партия до сих пор не завершена.
    # То такая партия нам абсолютно неинтересна, поскольку в задачах у нас просят значения, при которых Ваня или Петя побеждают максимум третьим ходом
    # Получается, что если в партии совершено много ходов, а она так и не завершилась, то мы её прерываем и начинаем просчёт другой позиции,
    # так как эта позиция нам становится неинтересной
    if first_heap * second_heap >= 2048:  # Если произведение камней в кучах стало больше 2047
        return 0  # Прекращаем игру
    if count_moves > 6: # если в игре больше 6 ходов
        return 10**10 # прерываем игру
    moves = [game(first_heap, second_heap+1,count_moves+1), game(first_heap+1, second_heap,count_moves+1),
             game(first_heap * 2, second_heap,count_moves+1),game(first_heap, second_heap * 2,count_moves+1)]  # Генерация всех возможных ходов
    petya_win = [i for i in moves if i <= 0]
    if petya_win: # если в данной позиции есть выигрыш Пети
        return -max(petya_win) + 1
    else: # если в данной позиции выигрыш Вани
        return -max(moves)


for i in range(1,187):
    # если в данной позиции возможен выигрыш Пети вторым ходом
    if game(11,i,0) == 2:
        print(i)

Ответ: 468592
Оцените статью
Я решу все!