Для игры, описанной в задании найдите минимальное значение
при котором одновременно выполняются два условия:
– у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;
– у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.
Решение руками
К моменту решения данной задачи уже известно, что при Петя будет побеждать своим первым ходом. При
будет побеждать Ваня первым ходом. При
и
победит Петя вторым ходом. Значит осталось рассмотреть значения
и найти минимальное, при котором Ваня победит своим вторым ходом.
Рассмотрим Из этой позиции Петя может сходить в
откуда он попадёт в выгодную для себя позицию и выиграет вторым ходом.
Рассмотрим Из этой позиции Петя может сходить в
откуда он попадёт в выгодную для себя позицию и выиграет вторым ходом.
Рассмотрим Из этой позиции Петя может сходить в
или
откуда уже Ваня попадёт в выгодную позицию и победит.
Решение программой
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 # Первое выведенное значение и будет минимальным