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

