19.01 Перекладывание камней одна куча
Ошибка.
Попробуйте повторить позже
Два игрока, Петя и Ваня, играют в следующую игру. Перед ними находится куча камней. Игроки ходят по очереди, первым ходит Петя. За один ход игрок может либо добавить в кучу 3 или 4 камня, либо сделать количество камней в куче равным квадрату текущего количества камней.
Например, если в куче 5 камней, то за один ход можно получить 8, 9 или 25 камней.
У каждого игрока есть неограниченное количество камней, чтобы делать ходы.
Игра завершается в тот момент, когда количество камней в куче становится не менее 627. Победителем считается
игрок, сделавший последний ход, т.е. первым получивший кучу из 627 камней или больше. В начальный момент в куче
было S камней; . Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при
любых ходах противника.
Найдите количество значений S, при которых Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.
Решение руками
Если начальное значение будет более , то и его квадрат будет более
, что даст Пете автоматическую победу.
Рассмотрим значения менее или равные
.
При Петя не сможет достичь
, но будет обязан увеличить значение как минимум на
, что даст Ване
возможность выиграть возведением в квадрат.
При всё абсолютно аналогично, как и при
.
При значении и ниже Петя сможет спокойно прибавить
, не давая Ване выиграть, получается, что у нас всего
подходящих значения.
Ответ:
Решение программой:
Для решения на Python используем рекурсию с проверкой всех возможных ходов (,
, возвести в квадрат),
чтобы определить, чья это выигрышная позиция.
Функция возвращает , если игра уже завершена (камней
), положительное число — если при оптимальной
игре побеждает текущий игрок, и отрицательное – если побеждает соперник.
Так как первый ход делает Петя, цикл запускается от его лица: если значение функции положительное, выигрвает
Пете, а если отрицательное – Ваня. Если функция вернёт - значит Петя гарантированно проиграл первым ходом,
а Ваня выиграл. При переборе возможных начальных значений программа выводит различные значения, их количество
-
.
# lru_cache позволит сэкономить ресурсы компьютера. Функция будет сохранять прошлые значения функций, а значит не придётся считать из заново. from functools import lru_cache @lru_cache(None) def game(first_heap): # Функция игры if first_heap >= 627: # Если камней в куче стало больше 627 return 0 # Прекращаем игру moves = [game(first_heap + 4), game(first_heap + 3), game(first_heap ** 2)] # Прописываем ходы возможные в партии petya_win = [i for i in moves if i <= 0] if petya_win: # Проверяем есть ли выигрыш Пети в данной позиции return -max(petya_win) + 1 # От лица Пети будет выигрыш (положительное число, прибавляем 1, поскольку это будет уже следующий ход) else: # Если в данной позиции выигрыш Вани return -max(moves) # От лица Пети будет проигрыш (отрицательное число) for i in range(2, 201): # Переберём возможные значения (единицу не берём из-за возведения в квадрат, ведь программа будет бесконечной) if game(i) == -1: # Если в данной позиции возможен выигрыш Вани первым ходом print(i) # Выведем нужное значение
Специальные программы

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

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

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

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

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

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