Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежат две кучи камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в одну из куч (по своему выбору) один камень или увеличить количество камней в куче
Игра завершается в тот момент, когда суммарное количество камней в кучах становится
В начальный момент в первой куче было семь камней, во второй куче —
Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника. Описать стратегию игрока — значит, описать, какой ход он должен сделать в любой ситуации, которая ему может встретиться при различной игре противника. В описание выигрышной стратегии не следует включать ходы играющего по этой стратегии игрока, не являющиеся для него безусловно выигрышными, то есть не являющиеся выигрышными независимо от игры противника.
Найдите минимальное значение S, при котором одновременно выполняются два условия:
— у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;
— у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.
Такое значение S — 30. При S = 30 Петя своим первым ходом может получить одну из четырёх позиций: (7, 31), (8, 30), (14, 30), (7, 60).
В позиции (7, 60) Ваня удваивает количество камней во второй куче и выигрывает своим первым ходом.
Из позиций (14, 30) и (7, 31) Ваня может получить позицию (14, 31). В этом случае после второго хода Пети может возникнуть одна из четырёх позиций: (15, 31), (14, 32), (28, 31), (14, 62). Во всех случаях Ваня удваивает количество камней во второй куче и выигрывает своим вторым ходом.
Из позиции (8, 30) Ваня своим первым ходом может получить позицию (16, 30). После второго хода Пети может возникнуть одна из четырёх позиций: (17, 30), (16, 31), (32, 30), (16, 60). Во всех случаях Ваня удваивает количество камней во второй куче и выигрывает своим вторым ходом.
Таким образом, ответ — 30.
Ответ: 30.
Примечание. Докажем, что при S ≤ 29 либо выигрывает Петя своим первым или вторым ходом, либо игра не завершится
При S ≤ 7 Петя своим первым ходом может добавить в большую кучу один камень. Тогда, даже если изначально S = 7, наибольшее количество камней, которое можно получить суммарно в обеих кучах
При 8 ≤ S ≤ 16 Петя может выбрать такую стратегию, которая не позволит победить Ване за один или два хода. Для этого Петя каждый ход может прибавлять к первой куче один камень. При этом наибольшее суммарное количество камней в обеих кучах, которое можно получить
При S = 17. Петя первым ходом может получить позицию (7, 18). Из этой позиции Ваня может получит позиции (8, 18), (7, 19), (14, 18) и (7, 36). В позиции (7, 36) Петя выигрывает своим вторым ходом. В остальных позициях у Пети есть стратегия, которая позволяет ему получить позиции, из которых Ваня не сможет выиграть своим вторым ходом.
При 18 ≤ S ≤ 29 Петя может получить позицию (8, S). В этой позиции Петя либо выигрывает своим вторым ходом, либо у него есть стратегия, которая позволяет ему получить позиции, в которых Ваня не может выиграть своим первым или вторым ходом.
Приведём решение на языке Python.
Исключим стратегию Вани, при которой он гарантировано выиграет первым ходом:
def f(x, y, h):
if (h == 3 or h == 5) and x + y >= 77:
return 1
elif h == 5 and x + y < 77:
return 0
elif x + y >= 77 and h < 5:
return 0
else:
if h % 2 == 0:
return f(x + 1, y, h + 1) or f(x, y + 1, h + 1) or f(x * 2, y, h + 1) or f(x, y * 2, h + 1) # стратегия победителя
else:
return f(x + 1, y, h + 1) and f(x, y + 1, h + 1) and f(x * 2, y, h + 1) and f(x, y * 2, h + 1) # стратегия проигравшего(любой ход)
def f1(x, y, h):
if h == 3 and x + y >= 77:
return 1
elif h == 3 and x + y < 77:
return 0
elif x + y >= 77 and h < 3:
return 0
else:
if h % 2 == 0:
return f1(x + 1, y, h + 1) or f1(x, y + 1, h + 1) or f1(x * 2, y, h + 1) or f1(x, y * 2, h + 1) # стратегия победителя
else:
return f1(x + 1, y, h + 1) and f1(x, y + 1, h + 1) and f1(x * 2, y, h + 1) and f1(x, y * 2, h + 1) # стратегия проигравшего(любой ход)
for x in range(1, 70):
if f(x, 7, 1) == 1:
print(x)
print("====")
for x in range(1, 70):
if f1(x, 7, 1) == 1:
print(x)
Приведём решение Михаила Глинского на языке Python.
def f(x,y,n):
if n%2==0 and (x+y)>=77: return 1
if n==4 and (x+y)<77: return 0
if n%2==1 and (x+y)>=77: return 0
else:
if n%2==0: return f(x+1,y,n+1) and f(x*2,y,n+1) and f(x,y+1,n+1) and f(x,y*2,n+1)
if n%2==1: return f(x+1,y,n+1) or f(x*2,y,n+1) or f(x,y+1,n+1) or f(x,y*2,n+1)
for s in range(1,70):
if f(7,s,0):
print(s)
break

