Задача к ЕГЭ по информатике на тему «перекладывание камней одна куча» №1

Два игрока, Петя и Ваня, играют в следующую игру. Перед игроками лежит одна куча камней. Игроки ходят по очереди, первый ход делает Петя. За один ход игрок может добавить в кучу один камень или увеличить количество камней в куче в два раза. Для того чтобы делать ходы, у каждого игрока есть неограниченное количество камней.

Игра завершается в тот момент, когда количество камней в куче становится не менее 185  . Победителем считается игрок, сделавший последний ход, т.е. первым получивший такую позицию, при которой в куче будет 185  или больше камней. В начальный момент в куче было S  камней; 1 ≤ S ≤ 184  .

Будем говорить, что игрок имеет выигрышную стратегию, если он может выиграть при любых ходах противника.

Укажите такое значение S  , при котором Петя не может выиграть за один ход, но при любом ходе Пети Ваня может выиграть своим первым ходом.

Решение руками

Для начала определим значения, при которых Петя побеждает первым ходом. Максимальный ход доступный нам в партии это ∗2  . Минимальное значение отрезка значений, в которых Петя побеждает первым ходом равняется: 185 = 92,5  2  (округляем в большую сторону) = 93

Получается, что в отрезке [93;184] Петя выигрывает своим первым ходом. Теперь определим значение, в котором Ваня побеждает своим первым ходом. Значение, из которого ВСЕ ходы ведут в вышеописанный отрезок – это значение, в котором Ваня выигрывает своим первым ходом. Распишем значение и стратегии, при которых Ваня побеждает первым ходом:

S = 92  . Петя может увеличить количество камней до 93  или 184  камней. Во всех этих случаях Ване не составит труда завершить партию следующим ходом.

Ответ: 92

Решение БУ

from functools import lru_cache
@lru_cache(None)
def game(first_heap): # функция игры
    if first_heap >= 185: # если камней в куче стало больше 184
        return 0 # прекращаем игру
    moves = [game(first_heap+1),game(first_heap*2)] # прописываем ходы возможные в партии
    petya_win = [i for i in moves if i <= 0]
    if petya_win: # проверяем есть ли выигрыш Пети в данной позиции
        return -max(petya_win) + 1
    else: # если в данной позиции выигрыш Вани
        return -max(moves)

for i in range(1,185):
    if game(i) == -1: # если в данной позиции возможен выигрыш Вани первым ходом
        print(i)

Решение АР

from functools import lru_cache

def m(h):
    return h * 2, h + 1

@lru_cache(None)
def f(h):
    if h >= 185:
        return "END"
    if any(f(x) == "END" for x in m(h)):
        return "P1"
    if all(f(x) == "P1" for x in m(h)):
        return "V1"
for i in range(1, 185):
    if f(i) == "V1":
        print(i)

Ответ: 92
Оцените статью
Я решу все!