Решение. Такое значение 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 либо выигрывает Петя своим первым или вторым ходом, либо игра не завершится за 4 хода.
При S ≤ 7 Петя своим первым ходом может добавить в большую кучу один камень. Тогда, даже если изначально S = 7, наибольшее количество камней, которое можно получить суммарно в обеих кучах за 4 хода, каждый раз удваивая большую кучу, равняется 71.
При 8 ≤ S ≤ 16 Петя может выбрать такую стратегию, которая не позволит победить Ване за один или два хода. Для этого Петя каждый ход может прибавлять к первой куче один камень. При этом наибольшее суммарное количество камней в обеих кучах, которое можно получить за 4 хода, равно 9 + 64 = 73.
При 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
Приведём решение Георгия Вострикова на языке Python.
def f(k1, k2, hod):
# hod - номер хода. 1 - первый ход Пети, 2 - первый ход Вани, 3 - второй ход Пети, 4 - второй ход Вани
if hod == who_win and k1 + k2 >= win_sum:
# нужный игрок победил на нужном ходе
return 1
elif hod == who_win and k1 + k2 < win_sum:
# нужный игрок не победил на нужном ходе
return 0
elif hod < who_win and k1 + k2 >= win_sum:
# Петя или Ваня победил раньше времени
if ZADANIE != 21:
return 0
elif hod == who_win-2:
# в №21 допускаем победу Вани первым ходом(раньше времени, когда hod == 3)
return 1
# дальше начинается сам ход игрока
# ПРИМЕР: если hod = 3, то выше мы проверили не победил ли Ваня после своего первого хода
# если ещё не победил, тогда уже делаем второй ход Пети
else:
# hod - чётный, значит, сейчас ходит Ваня, иначе(нечёт) Петя
if hod % 2 == 0:
# действия Вани с кучами (по условию: k1/k2 + 1 и k1/k2 * 2)
if ZADANIE == 19 or ZADANIE == 21:
# играем за Ваню, подойдёт любое удобное дейтсвие(or)
return f(k1, k2 + sum2, hod + 1) or f(k1 + sum1, k2, hod + 1) or f(k1, k2 * x2, hod + 1) or f(k1 * x1, k2, hod + 1)
elif ZADANIE == 20:
# играем против Вани, проверяем все его возможные действия(and)
return f(k1, k2 + sum2, hod + 1) and f(k1 + sum1, k2, hod + 1) and f(k1, k2 * x2, hod + 1) and f(k1 * x1, k2, hod + 1)
else:
# действия Пети с кучами (по условию: k1/k2 + 1 и k1/k2 * 2)
if ZADANIE == 19 or ZADANIE == 20:
# играем против Пети или за Петю, подойдёт любое неудачное/удачное действие Пети(or)
return f(k1, k2 + sum2, hod + 1) or f(k1 + sum1, k2, hod + 1) or f(k1, k2 * x2, hod + 1) or f(k1 * x1, k2, hod + 1)
elif ZADANIE == 21:
# играем против Пети, проверяем все его возможные действия(and) для победы Вани 2ым ходом
if who_win == 5:
return f(k1, k2 + sum2, hod + 1) and f(k1 + sum1, k2, hod + 1) and f(k1, k2 * x2, hod + 1) and f(k1 * x1, k2, hod + 1)
elif who_win == 3:
# играем против Пети: проверяем, что не при любых ходах Пети, Ваня может выиграть первым ходом
if ((f(k1, k2 + sum2, hod + 1) + f(k1 + sum1, k2, hod + 1) + f(k1, k2 * x2, hod + 1) + f(k1 * x1, k2, hod + 1)) < kol):
return 1
# УСЛОВИЯ ЗАДАЧИ ------------------------------------------------
sum1 = 1 # сколько можно прибавлять в 1ую кучу
sum2 = 1 # сколько можно прибавлять во 2ую кучу
x1 = 2 # во сколько раз можно умножать 1ую кучу
x2 = 2 # во сколько раз можно умножать 2ую кучу
kol = 4 # количество вариантов действий с кучами
k1 = 7 # количество камней в 1ой куче
win_sum = 77 # общая сумма камней от которой начинается победа
k2_max = 69 # максимальное S(количество камней во 2ой куче)
# НОМЕР ЗАДАЧИ --------------------------------------------------
ZADANIE = 21 # для какого задания программа (19, 20 или 21)
if ZADANIE == 19:
# who_win - кто должен выиграть и каким ходом?
who_win = 3 # №19 - Ваня первым ходом
elif ZADANIE == 20:
who_win = 4 # №20 - Петя вторым ходом
elif ZADANIE == 21:
who_win = 5 # №21 - Ваня вторым ходом
for k2 in range(1, k2_max):
if f(k1, k2, 1) == 1:
if ZADANIE == 21:
who_win = 3 # проверяем, что не при любых ходах Пети, Ваня может выиграть первым ходом
if f(k1, k2, 1) == 1:
print(k2)
break
else:
print(k2)
if ZADANIE != 20:
break