Задания 19-21. Информатика. ЕГЭ. Статград. 04.03.2025

Просмотры: 493
Изменено: 4 марта 2025

19

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

Например, если в куче \(6\) камней, то за один ход можно добавить \(1,\) \(2,\) \(3\) или \(6\) камней. Игра завершается, когда количество камней в куче становится более \(91.\) Победителем считается игрок, сделавший последний ход, то есть первым получивший кучу, в которой будет \(92\) или больше камней. В начале игры в куче было \(S\) камней, \(S < 92.\) Укажите минимальное значение \(S,\) при котором Петя не может выиграть первым ходом, но при любом первом ходе Пети Ваня может выиграть своим первым ходом.

20

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

21

Для игры, описанной в задании 19, найдите минимальное значение \(S,\) при котором у Вани есть стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети, но у Вани нет стратегии, которая позволила бы ему гарантированно выиграть первым ходом.

Решение:

Python


def divisors(n):
    d = {1, n}
    for x in range(2, int(n**0.5) + 1):
        if n % x == 0:
            d.add(x)
            d.add(n // x)
    return d

def moves(h):
    return tuple(h + d for d in divisors(h))

def game_over(pos):
    return pos > 91

def win1(pos):
    return not game_over(pos) and any(game_over(m) for m in moves(pos))

def lose1(pos):
    return all(win1(m) for m in moves(pos))

def win2(pos):
    return not win1(pos) and any(lose1(m) for m in moves(pos))

def lose2(pos):
    return all(win1(m) or win2(m) for m in moves(pos)) \
        and any(win2(m) for m in moves(pos))

z19 = [S for S in range(1, 92) if lose1(S)]
z20 = [S for S in range(1, 92) if win2(S)]
z21 = [S for S in range(1, 92) if lose2(S)]
print(min(z19))
print(min(z20), max(z20))
print(min(z21))

Ответ:
\(45\)
\(30 \,\, 44\)
\(29\)