19.04 Уменьшение количества камней
Ошибка.
Попробуйте повторить позже
Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может: убрать из кучи три камня, или убрать из кучи семь камней, или уменьшить количество камней в куче в четыре раза (количество камней, полученное при делении, округляется до меньшего). Например, из кучи в 21 камень за один ход можно получить кучу из 18, 14 или 5 камней.
Игра завершается, когда количество камней в куче становится не более 21.
Победителем считается игрок, сделавший последний ход, то есть первым получивший кучу, в которой будет 21 или меньше камней.
В начальный момент в куче было S камней, S .
Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.
Укажите минимальное значение S, при котором Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.
Решение руками
Для начала определим значения, из которых Петя выигрывает за один ход. Максимально уменьшить
количество камней можно, поделив на , поэтому максимальное значение для победы за один ход равно
. Если учитывать округление вниз, числа до
также приводят к победе за один ход. Таким
образом, при
игрок побеждает за один ход. Чтобы Ваня мог выиграть при любом ходе Пети,
Петя должен передать Ване выигрышную позицию, то есть все свои ходы должны привести к диапазону
. Это возможно при
. В ответ записываем минимальное значение
, то есть
.
Решение программой
Для решения на Python используем рекурсию с проверкой всех возможных ходов, чтобы определить, чья это
выигрышная позиция. Функция возвращает , если игра уже завершена (камней
), положительное число – если
при оптимальной игре побеждает текущий игрок, и отрицательное – если побеждает соперник. Так как первый ход
делает Петя, цикл запускается от его лица: если значение функции положительное, выигрыш принадлежит Пете, а если
отрицательное – Ване. При переборе возможных
программа находит три числа S, в ответ записываем
минимальное
from functools import lru_cache @lru_cache(None) # Кэширует предыдущие значения функции, что позволяет ускорить работу программы def game(first_heap): # Функция игры if first_heap <= 21: # Если камней в куче стало не более 21 return 0 # Прекращаем игру moves = [game(first_heap - 3), game(first_heap - 7), game(first_heap // 4)] # Прописываем возможные ходы в партии win = [i for i in moves if i <= 0] if win: # Проверяем, есть ли выигрыш в данной позиции return -max(win) + 1 else: # Если в данной позиции выигрыш соперника return -max(moves) for i in range(22, 100): if game(i) == -1: # Если в данной позиции возможен выигрыш Вани первым ходом print(i)
Специальные программы

Программа
лояльности v2.0
Приглашай друзей в Школково и получай вознаграждение до 10%!

Крути рулетку
и выигрывай призы!
Крути рулетку и покупай курсы со скидкой, которая привязывается к вашему аккаунту.

Бесплатное онлайн-обучение
Для школьников из приграничных территорий России, проживающих в ДНР, ЛНР, Херсонской, Запорожской, Белгородской, Курской, Брянской областях и Крыму.

Налоговые вычеты
Узнай, как получить налоговый вычет при оплате обучения в «Школково».

Специальное предложение
для учителей
Бесплатный доступ к любому курсу подготовки к ЕГЭ, ОГЭ и олимпиадам от «Школково». Мы с вами делаем общее и важное дело, а потому для нас очень значимо быть чем-то полезными для учителей по всей России!

Вернём деньги за курс
за твою сотку на ЕГЭ
Сдать экзамен на сотку и получить обратно деньги за подготовку теперь вполне реально!