Решение 1. Анализ через f(a, b, m)
🔹 Шаг 1. Создаем рекурсивную функцию
def f(a, b, m):
📌 Функция определяет, может ли текущий игрок гарантированно победить за m ходов.
🔹 Шаг 2. Проверяем окончание игры
if a + b >= 155 or m < 0:
📌 Если сумма камней уже не меньше 155 или ходы закончились, рекурсия завершается.
🔹 Шаг 3. Возвращаем результат
return m % 2 == 0
📌 Чётность m показывает, чей ход оказался победным.
🔹 Шаг 4. Перебираем все возможные ходы
h = f(a + 1, b, m - 1), f(a * 3, b, m - 1), f(a, b + 1, m - 1), f(a, b * 3, m - 1)
📌 Четыре действия: +1 или ×3 для первой или второй кучи.
🔹 Шаг 5. Выбираем any
return any(h)
📌 Для задания 19 с «неудачного» хода Пети достаточно any.
✅ Задание 19
📌 Найти минимальное S, при котором после неудачного хода Пети Ваня выигрывает своим первым ходом.
print(19, [s for s in range(1, 140) if f(15, s, 2)])
📌 Проверяем f(15, S, 2). Минимальное значение: 16.
🔹 Для заданий 20 и 21 меняем any на any/all
return any(h) if (m - 1) % 2 == 0 else all(h)
📌 На своём ходу — any, на ходе соперника — all.
✅ Задание 20
📌 Найти два наименьших S, когда Петя не выигрывает сразу, но гарантированно выигрывает своим вторым ходом.
ans = [s for s in range(1, 140) if not f(15, s, 1) and f(15, s, 3)]
print(*sorted(set(ans))[:2])
📌 Два наименьших: 19 и 46.
✅ Задание 21
📌 Найти минимальное S, когда Ваня выигрывает первым или вторым ходом, но не имеет гарантированной победы первым ходом.
print([s for s in range(1, 140) if not f(15, s, 2) and f(15, s, 4)])
📌 Ответ: 45.