Решение 1. Анализ через f(a, b, m)
🔹 Шаг 1. Создаем рекурсивную функцию
def f(a, b, m):
📌 Функция определяет, может ли текущий игрок гарантированно победить за m ходов.
🔹 Шаг 2. Проверяем окончание игры
if a + b <= 47 or m < 0:
📌 Если сумма камней уже не больше 47 или ходы закончились, рекурсия завершается.
🔹 Шаг 3. Возвращаем результат
return m % 2 == 0
📌 Чётность m показывает, чей ход оказался победным.
🔹 Шаг 4. Перебираем все возможные ходы
h = f(a - 2, b, m - 1), f(a // 3, b, m - 1), f(a, b - 2, m - 1), f(a, b // 3, m - 1)
📌 Четыре действия: −2 или // 3 для первой или второй кучи.
🔹 Шаг 5. Выбираем any
return any(h)
📌 Для задания 19 с «неудачного» хода Пети достаточно any.
✅ Задание 19
📌 Найти минимальное S, при котором после неудачного хода Пети Ваня выигрывает своим первым ходом.
print(19, [s for s in range(32, 1001) if f(16, s, 2)])
📌 Проверяем f(16, S, 2). Минимальное значение: 34.
🔹 Для заданий 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(32, 1001) if not f(16, s, 1) and f(16, s, 3)]
print(min(ans), max(ans))
📌 Наименьшее и наибольшее: 98 и 293.
✅ Задание 21
📌 Найти минимальное S, когда Ваня выигрывает первым или вторым ходом, но не имеет гарантированной победы первым ходом.
print([s for s in range(32, 1001) if not f(16, s, 2) and f(16, s, 4)])
📌 Ответ: 100.