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

Для игры, описанной в задании 37,  найдите минимальное значение S,  при котором одновременно выполняются два условия:

– у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;

– у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.

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

К моменту решения данной задачи уже известно, что при S = 3,4,5,6  Петя будет побеждать своим первым ходом. При S = 7,8,12  будет побеждать Ваня первым ходом. При S = 9  и S = 36  победит Петя вторым ходом. Значит осталось рассмотреть значения S = 10,11,13,14...  и найти минимальное, при котором Ваня победит своим вторым ходом.

Рассмотрим S = 10.  Из этой позиции Петя может сходить в S = 7,  откуда он попадёт в выгодную для себя позицию и выиграет вторым ходом.

Рассмотрим S = 11.  Из этой позиции Петя может сходить в S = 8,  откуда он попадёт в выгодную для себя позицию и выиграет вторым ходом.

Рассмотрим S = 13.  Из этой позиции Петя может сходить в S = 10  или S = 11,  откуда уже Ваня попадёт в выгодную позицию и победит.

 

Решение программой

from functools import lru_cache


@lru_cache(None)
def game(heap):  # Функция игры

    if heap <= 2:  # Если куча меньше или равна 2
        return 0  # Возвращаем стартовое значение 0

    # Список для возможных ходов,
    # которые нужно добавить в зависимости от условий
    steps = []
    # 1 Условие
    if heap % 2 == 0:
        steps += [game(heap // 2)]  # Убираем половину
    else:
        steps += [game(heap - 2)]  # Убираем 2 камня
    # 2 Условие
    if heap % 3 == 0:
        steps += [game(heap // 3)]  # Убрать две трети равносильно оставить одну треть
    else:
        steps += [game(heap - 3)]  # Убираем 3 камня

    petya_win = [x for x in steps if x <= 0]  # Выигрышные позиции для пети

    if petya_win:  # Если такие значения есть
        return -max(petya_win) + 1
    return -max(steps)


for s in range(3, 100):
    if game(s) == -2:  # Если Ваня смог победить гарантированно за 2 хода
        print(s)
        break  # Первое выведенное значение и будет минимальным

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