Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу один камень, добавить два камня или увеличить количество камней в куче в два раза. При этом нельзя повторять ход, который этот же игрок делал на предыдущем ходу. Повторять чужие ходы и свои более старые ходы разрешается.
Например, если в начале игры в куче
Чтобы делать ходы, у каждого игрока есть неограниченное количество камней.
Игра завершается, когда количество камней в куче становится
Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.
Укажите наименьшее
Такое значение S — 12. Своим первым ходом Петя может получить
Ответ: 12.
Приведём другое решение на языке Python.
Для контроля ходов игроков заведём переменную m.
Если m = 1, то это действие x + 1.
Если m = 2, то это действие x + 2.
Если m = 3, то это действие x · 2.
Таким образом, можно исключать ходы, которые уже были сделаны, не включая их в возвращаемые значения функции.
def f(x, h, m):
if h == 4 and x >= 29:
return 1
elif h == 4 and x < 29:
return 0
elif x >= 29 and h < 4:
return 0
else:
if h % 2 != 0:
if h == 1:
return f(x + 1, h + 1, 1) or f(x + 2, h + 1, 2) or f(x * 2, h + 1, 3) # стратегия победителя
elif h == 3:
if m == 1:
return f(x + 2, h + 1, m) or f(x * 2, h + 1, m)
elif m == 2:
return f(x + 1, h + 1, m) or f(x * 2, h + 1, m)
elif m == 3:
return f(x + 1, h + 1, m) or f(x + 2, h + 1, m)
else:
return f(x + 1, h + 1, m) and f(x + 2, h + 1, m) and f(x * 2, h + 1, m)
for x in range(1, 29):
if f(x, 1, 0) == 1:
print("Задача 19:", x)
break
Приведём решение Юрия Красильникова на языке Python.
def move(n,lim,s,t):
player = 2-n%2
rival = 3-player
if s >= 29:
return rival
if n > lim:
return 0
pos=[(s+1,0),(s+2,1),(s*2,2)]
if len(t) >= 2:
del pos[t[-2]]
res = [move(n+1,lim,p[0],t+[p[1]]) for p in pos]
if any([r==player for r in res]):
return player
if all([r==rival for r in res]):
return rival
return 0
print('#19:',*[s for s in range(1,29) if move(1,1,s,[])==0 and move(1,3,s,[])==1])
print('#20:',*[s for s in range(1,29) if move(1,2,s,[])==0 and move(1,4,s,[])==2])
print('#21:',*[s for s in range(1,29) if move(1,3,s,[])==0 and move(1,5,s,[])==1])

