Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу два или четыре камня либо увеличить количество камней в куче в три раза. Например, из кучи в 10 камней можно получить кучу из 12, 14 либо 30 камней. У каждого игрока есть неограниченное количество камней, чтобы делать ходы. Игра завершается в тот момент, когда количество камней в куче становится не менее 271. Победителем считается игрок, сделавший последний ход, т.е. первым получивший кучу из 271 или более камня. В начальный момент в куче было S камней; 1 S
270. Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.
Укажите максимальное значение S, при котором Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.
Решение руками
Максимальный ход, который мы имеем в игре это , это значит, что промежуток, в котором игрок выигрывает в один ход располагается от
до
.
Из этого следует, что наибольшее значение, при котором Ваня выиграет первым ходом это .
Решение БУ
from functools import lru_cache
lru_cache(None)
def f(a,c):# Параметр ’с’ в этой программе - это счётчик,сделанных ходов в данной партии.
# В данной задаче он обязателен,поскольку изначальное кол-во камней может быть слишком мало,а также есть ходы,которые не так сильно увеличивают кол-во камней в куче(+2,+4),как,например ход (*3).
# По этой причине у нас может возникнуть ошибка,связанная с превышением глубины рекурсии или же программа будет слишком долго высчитывать значения.
if a >= 271:return 0
if c > 10:return 1000 #Возвращаем очень большое значение,которое указывает программе,что при таком значении невозможно дойти до выигрыша при малом количестве ходов.
t = [f(a+2,c+1),f(a+4,c+1),f(a*3,c+1)]
n = [i for i in t if i <= 0]
if n:return -max(n) + 1
return -max(t)
for i in range(1,271):
if f(i,0) == -1:
print(f"19) {i}")