Ошибка Кода

Разбор заданий, лёгкий уровень
B. задача 2 лёгкая
Миша заполнял таблицу истинности логической функции F=c∧¬b∨c∧a, но успел заполнить лишь фрагмент из трёх различных её строк, даже не указав, какому столбцу таблицы соответствует каждая из переменных a, b, c.
Таблица истинности
Определите, какому столбцу таблицы истинности функции F соответствует каждая из переменных c, b, a.
В ответе напишите буквы c, b, a в том порядке, в котором идут соответствующие им столбцы (сначала буква, соответствующая первому столбцу; затем буква, соответствующая второму столбцу, и т.д.). Буквы в ответе пишите подряд, никаких разделителей между буквами ставить не нужно.
Решение
Для решения этой задачи мы воспользуемся перебором.
Для этого нужно подставить переменные a, b, c в таблицу во всех возможных комбинациях. Если результаты функции совпадёт во всех строках, то такое расположение нам подойдёт.

Сначала подставим a в первый столбик, b во второй, с в третий. Далее переберём все возможные варианты. Для перебора всех вариантов воспользуемся permutations () из библиотеки itertools. permutations () составляет все возможные варианты перестановок. Результатом permutations ([0, 1, 2]) будет (0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)

Давайте разберем код построчно:
# permutations составит все возможные варианты перестановок
from itertools import permutations

# перепишем логическую функцию на язык python
def f(a, b, c):
    return c and (not b) or c and a

# переписываем таблицу
data = [
    [0, 1, 0],
    [0, 1, 1],
    [1, 1, 1],
]
# перебираем варианты позиций переменных
# например, a, b, c = 0, 1, 2 означает, что 
# a - первый столбец, b - второй, c - третий
for a, b, c in permutations([0, 1, 2]):
    # если для всех строк функция равна единице,
    # то такое расположение подходит
    ok = True
    for line in data:
        if f(line[a], line[b], line[c]) != 1:
            ok = False
    if ok:
        # чтобы вывести ответ, подставим буквы на свои места
        answer = ['', '', '']
        answer[a] = 'a'
        answer[b] = 'b'
        answer[c] = 'c'
        print(answer[0] + answer[1] + answer[2])
# ответ: bca
Ответ: bca
С. задача 5 лёгкая
На вход программы подаётся натуральное число N. Программа преобразует число N в новое число R по следующему алгоритму:

  1. Преобразуется число N в его двоичное представление.
  2. К полученной двоичной записи добавляются дополнительные разряды согласно следующим условиям:
    а. Если количество единиц в записи четное количество, к началу строки добавляется 11.
    b. Если количество единиц в записи нечетное количество, к концу строки добавляется 00.

Полученная таким образом запись является двоичной записью искомого R.

Пример:
9 → 10012 →1110012 → 57
Укажите минимальное число N, при вводе которого получится значение 
R больше, чем 116.
В ответе полученное число запишите в десятичной системе.
Решение
Для решения этой задачи мы используем цикл для перебора всех чисел от 1 до 100.

Для каждого числа мы делаем следующее:

  1. Преобразуем число в его двоичное представление.
  2. Проверяем, четное ли количество единиц в этой двоичной записи.
  3. В зависимости от четности количества единиц, добавляем к двоичной строке либо «11» в начало, либо «00» в конец.
  4. Преобразуем полученную двоичную строку обратно в десятичное число.
  5. Проверяем, больше ли это число 116.
    Если условие выполнено, мы прекращаем перебор и выводим текущее число.
Давайте разберем код построчно:
# Перебор всех чисел от 1 до 100
for N in range(1, 100):
    # Преобразование числа N в двоичную строку
    r = bin(N)[2:]
    # Проверка четности количества единиц в двоичной записи
    if r.count("1") % 2 == 0:
        # Добавление '11' в начало строки
        r = "11" + r
    else:
        # Добавление '00' в конец строки
        r = r + "00"
    # Преобразование обратно в десятичное число
    r = int(r, 2)
    # Проверка условия R > 116
    if r > 116:
        print(N)
        break
Ответ: 23
D. задача 8 лёгкая
Все шестибуквенные слова, составленные из букв Я, Н, Д, Е, К, С, записаны в алфавитном порядке и пронумерованы начиная с 1.
Вот начало списка:
  1. ДДДДДД
  2. ДДДДДЕ
  3. ДДДДДК
  4. ДДДДДН
  5. ДДДДДС
  6. ДДДДДЯ
  7. ДДДДЕД ...
Под каким номером в списке стоит слово «ЯНДЕКС»?
Решение
1 вариант
Для решения этой задачи мы используем концепцию перебора всех возможных комбинаций из заданных букв.
Мы создаем комбинации слов длины 6 из букв «ДЕКНСЯ» и проверяем, совпадает ли текущая комбинация с искомым словом «ЯНДЕКС». При каждом шаге увеличивается счетчик, который отображает текущую позицию комбинации. Как только находим искомое слово, выводим его позицию и завершаем перебор.
Давайте разберем код построчно:
from itertools import product

n = 0  # Счетчик позиции
# Перебор всех возможных комбинаций слов из заданных букв
for i in product("ДЕКНСЯ", repeat=6):
    s = ''.join(i)  # Преобразование кортежа в строку
    n += 1  # Увеличение счетчика позиции
    # Проверка, совпадает ли текущая комбинация с искомым словом
    if s == "ЯНДЕКС":
        print(n)
        break  # Прекращение цикла, если слово найдено
2 вариант
Для решения этой задачи мы используем другой подход, чем в предыдущем варианте.
Вместо того, чтобы перебирать все комбинации в цикле и проверять каждую, мы сразу генерируем список всех возможных комбинаций из заданных букв. После этого, используя метод поиска элемента в списке, мы находим позицию искомого слова «ЯНДЕКС» в этом списке. Не забываем прибавить 1, так как индексация в списке начинается с нуля.
Давайте разберем код построчно:

from itertools import product

# Генерация всех возможных комбинаций слов из заданных букв
all_products = list(product('ДЕКНСЯ', repeat=6))

# Поиск позиции слова "ЯНДЕКС" в сгенерированном списке
print(all_products.index(tuple("ЯНДЕКС")) + 1)
Ответ: 42821
E. задача 9 лёгкая
Откройте файл в формате TXT (9.txt), содержащий в каждой строке три натуральных числа.
Вот первые строки файла 9.txt:
97 40 1
21 56 1
6 70 39
95 62 32
65 85 48
файл 9.txt можно открыть используя open()

Определите количество строк, для чисел которых выполняется оба условия:

  1. все числа различны;
  2. сумма чисел кратна трём.
Решение
Для решения этой задачи мы считываем данные из файла, каждую строку которого мы разбиваем на отдельные числа.

Эти числа мы преобразуем из строк в целые числа для дальнейших вычислений. Далее, для каждой строки, состоящей из трех чисел, мы выполняем две проверки:

  1. Все три числа должны быть разными. Для этого мы используем множество — если длина множества равна 3, то все числа разные. В множестве хранятся только уникальные элементы, например set([1, 1, 1]) = {1} Если в множестве останутся 3 элемента, значит они различны.
  2. Сумма трех чисел должна быть кратна 3.
Если оба условия выполнены, мы увеличиваем счетчик, который в конце работы программы покажет нам количество строк, удовлетворяющих условиям.
Давайте разберем код построчно:
# Счетчик для строк, соответствующих условиям
count = 0

# Открываем файл для чтения
with open("9.txt", "r") as file:
    # Проходим по каждой строке в файле
    for row in file:
        # Разделяем строку по символу ';'
        numbers = row.strip().split()

        # Преобразуем строки в числа
        for i in range(3):
            numbers[i] = int(numbers[i])

        # Проверяем условия
        if len(set(numbers)) == 3 and sum(numbers) % 3 == 0:
            count += 1

# Выводим результат
print(count)
Ответ: 610
F. задача 12 лёгкая
Исполнитель редактор принимает на вход строку цифр и может выполнять две команды:
  1. Заменить (v, w)
    Эта команда заменяет в строке первое слева вхождение цепочки v на цепочку w. Например, выполнение команды заменить (333, 77) преобразует строку 333233 в строку 77233. Если в строке нет вхождений цепочки v, то выполнение команды заменить (v, w) не меняет эту строку.
  2. Нашлось (v)
    Эта команда проверяет, встречается ли цепочка v в строке исполнителя Редактор. Если она встречается, то команда возвращает логическое значение «истина», в противном случае возвращает значение «ложь». Строка исполнителя при этом не изменяется.
Дана программа для Редактора:
НАЧАЛО
ПОКА нашлось(7777) ИЛИ нашлось(33333)
   ЕСЛИ нашлось(33333)
      ТО заменить(33333, 777)
      ИНАЧЕ заменить(777, 33)
   КОНЕЦ ЕСЛИ
КОНЕЦ ПОКА
КОНЕЦ
Определите количество цифр 3 в строке, которая получится в результате применения приведённой ниже программы к строке, состоящей из 200 идущих подряд цифр 7.
В ответе запишите количество цифр 3 в полученной строке.
Решение
Для решения этой задачи мы начинаем с исходной строки, состоящей из 200 идущих подряд цифр 7.
Затем мы входим в цикл, который продолжается, пока в строке есть подстроки «7777» или «33333». В каждой итерации цикла мы делаем одно из двух:

  1. Если в строке есть подстрока «33333», мы заменяем её на «777».
  2. Если нет, но есть подстрока «7777», мы заменяем её на «33».

Эти замены мы выполняем по одной за каждую итерацию цикла. В конце работы программы мы подсчитываем, сколько осталось цифр 3 в получившейся строке.

Давайте разберем код построчно:
# Исходная строка, состоящая из 200 идущих подряд цифр 7
s = "7" * 200

# Выполняем цикл, пока в строке находятся подстроки "7777" или "33333"
while "7777" in s or "33333" in s:
    # Если находится подстрока "33333", заменяем её на "777"
    if "33333" in s:
        s = s.replace("33333", "777", 1)
    # В противном случае заменяем подстроку "7777" на "33"
    else:
        s = s.replace("777", "33", 1)

# Подсчитываем количество цифр 7 в получившейся строке
print(s.count("3"))
Ответ: 1
G. задача 13 лёгкая
Вы администратор сети в небольшой фирме. Компания только что приобрела новый принтер, и вам нужно подключить его к сети. У вас есть подсеть с IP-адресом 192.168.1.0 и маской сети 255.255.255.0. В этой подсети уже есть 50 подключенных устройств.
Сколько устройств еще можно подключить к этой подсети, после подключения принтера, не меняя маску сети?
Подсказка:
IP-адреса подсети и широковещательной передачи (broadcast) не могут быть использованы для устройств.
Решение

Для решения этой задачи мы используем библиотеку для работы с IP-адресами и сетями.

Сначала создаем объект сети с заданным адресом и маской подсети.

Затем мы перебираем все возможные IP-адреса в этой сети, увеличивая счетчик на 1 для каждого адреса.

В конце работы программы из общего числа адресов в сети мы вычитаем:

  • 2 адреса для шлюза и широковещательной рассылки (они не могут быть использованы для устройств),
  • 50 адресов, которые уже заняты,
  • 1 адрес, который использован для принтера.

Это дает нам количество оставшихся свободных IP-адресов в сети.

Давайте разберем код построчно:
from ipaddress import ip_network

count = 0  # Инициализация счетчика устройств
# Создание объекта сети с помощью функции ip_network
net = ip_network('192.168.1.0/255.255.255.0', strict=False)
# Перебор всех возможных IP-адресов в этой сети
for ip in net:
    count += 1
# Вычисление количества оставшихся свободных IP-адресов
print(count - 2 - 50 - 1)
Ответ: 203
H. задача 14 лёгкая
Расстояние от Земли до Солнца приблизительно равно 149 597 870 км.
Посчитай сколько нулей содержит 5-ричная запись этого числа.
Решение

Для решения этой задачи мы преобразуем исходное десятичное число в 5-ричную систему счисления.

Этот процесс включает в себя целочисленное деление исходного числа на 5 и сохранение остатков, которые образуют новое число в 5-ричной системе.

После того как число будет полностью преобразовано, мы подсчитываем количество нулей в получившейся 5-ричной записи числа.

Давайте разберем код построчно:
x = 149597870  # Исходное число (расстояние от Земли до Солнца)
n = ''  # Строка для хранения 5-ричной записи числа
# Цикл для перевода числа в 5-ричную систему счисления
while x > 0:
    n = str(x % 5) + n  # Добавление остатка от деления на 5 к строке n
    x = x // 5  # Целочисленное деление на 5
# Подсчет количества нулей в 5-ричной записи
print(n.count('0'))
Ответ: 2
I. задача 15 лёгкая
Обозначим как ДЕЛ(х, А) утверждение, что натуральное число х делится на А без остатка.
Для приведенного ниже выражения укажите минимальное натуральное А, при котором выражение будет истинно для любого х.
Выражение:
(ДЕЛ(x,30) ∧ ¬ДЕЛ(x,45)) → ¬ДЕЛ(x,A)
Решение
1 вариант

Для решения этой задачи мы используем два вложенных цикла.

Внешний цикл перебирает все возможные значения A от 1 до 100, а внутренний цикл проверяет, выполняется ли заданное условие для каждого x от 1 до 1000 при данном A.

Функция f(x) возвращает истину или ложь в зависимости от того, выполняется ли условие для заданных x и A.

Если для какого-то x условие не выполняется, текущее A считается недопустимым, и внутренний цикл прерывается.

Как только находится A, для которого условие выполняется для всех x, цикл останавливается, и это A выводится на экран.

Давайте разберем код построчно:
def f(x):
    # Проверка, что выражение истинно для данного x и A
    return ((x % 30 == 0) and (x % 45 != 0)) <= (x % a != 0)

# Поиск минимального A, для которого выражение истинно для всех x
for a in range(1, 100):
    a_is_ok = True
    for x in range(1, 1000):
        # если хоть в одной точке функция ложна,
        # то такое a нам не подходит
        if f(x) == 0:
            a_is_ok = False
            break
    if a_is_ok == True:
        print(a)
        break
2 вариант

Для решения этой задачи мы снова используем два цикла, но на этот раз вместо явного внутреннего цикла применяем функцию all.

Эта функция проверяет, выполняется ли условие f(x)=1 для всех x в заданном диапазоне (от 1 до 10,000).

Давайте рассмотрим простой пример с функцией all. Представьте, что у вас есть список чисел, и вы хотите проверить, все ли эти числа положительны.

Пример функции all:
numbers = [1, 2, 3, 4, 5]
result = all(x > 0 for x in numbers)

В этом примере all(x > 0 for x in numbers) вернёт True, потому что все числа в списке положительные.

Функция all пройдёт по каждому элементу списка и проверит условие x>0. Если хоть одно число не удовлетворяет этому условию, all вернёт False.

В вашей задаче функция all делает нечто похожее, но на более сложном уровне. Она проверяет, что функция f(x) возвращает 1 для всех x в заданном диапазоне. Если это так, то текущее значение A найдено и цикл прекращается.

Как только находим A, для которого условие выполняется для всех x, мы выводим это A и прекращаем цикл.

Давайте разберем код построчно:
def f(x):
    # Проверка, что выражение истинно для данного x и A
    return ((x % 30 == 0) and (x % 45 != 0)) <= (x % a != 0)

# Поиск минимального A, для которого выражение истинно для всех x
for a in range(1, 100):
    if all(f(x) == 1 for x in range(1, 10000)):  # Начинаем с 1, потому что x - натуральное число
        print(a)
        break
Ответ: 9
J. задача 16 лёгкая
Алгоритм вычисления значения функции F(n), где n — натуральное число, задан следующими соотношениями:
Подсказка:
F(n)=1 при n≤1;
F(n)=F (n−1) + F(n−1), если n>1 и n делится на 3;
F(n)=F(n−2) + 3∙n в остальных случаях.
Чему равно значение функции F(65)?
Решение

Для решения этой задачи мы используем рекурсивную функцию f (n), которая вычисляет значение на основе заданных условий.

Эта функция имеет три основных случая:

  1. Если n меньше или равно 1, функция просто возвращает 1.
  2. Если n делится на 3, функция вызывает себя дважды: с аргументами n−1 и n−3, а затем возвращает их сумму.
  3. В противном случае функция вызывает себя с n−2 и возвращает сумму этого результата и утроенного значения n.

В конце функция вызывается с аргументом 65, и полученный результат выводится на экран.

Суть решения заключается в рекурсивном вызове функции с различными аргументами в зависимости от заданных условий.

Давайте разберем код построчно:
# Определение функции f(n)
def f(n):
    # Если n <= 1, возвращаем 1
    if n <= 1:
        return 1
    # Если n делится на 3, возвращаем сумму результатов f(n - 1) и f(n - 3)
    if n % 3 == 0:
        return f(n - 1) + f(n - 3)
    # В противном случае возвращаем сумму результата f(n - 2) и утроенного значения n
    else:
        return f(n - 2) + 3 * n

# Выводим результат функции для n = 65
print(f(65))
Ответ: 33554423
K. задача 17 лёгкая
В файле содержится последовательность натуральных чисел.
Вот первые строки файла 17.txt:
7575
9502
6012
52
3253
файл 17.txt можно открыть используя open()
Элементы последовательности могут принимать значения от 1 до 10 000 включительно.
Определите количество пар последовательности, в которых только одно число является трёхзначным, а сумма элементов пары не меньше максимального трёхзначного элемента последовательности.

Определите количество пар последовательности, в которых только одно число является трёхзначным, а сумма элементов пары не меньше максимального трёхзначного элемента последовательности.

В ответе запишите количество найденных пар, затем максимальную из сумм элементов таких пар через пробел.

В данной задаче под парой подразумевается два идущих подряд элемента последовательности.

Решение
Для решения этой задачи мы сначала читаем числа из файла и сохраняем их в список, при этом находим максимальное трехзначное число среди всех чисел.
Затем мы перебираем все соседние пары чисел в этом списке. Для каждой пары мы проверяем два условия:

  1. Одно из чисел трехзначное, а другое — нет.
  2. Сумма чисел пары больше или равна максимальному трехзначному числу, найденному ранее.

Если оба условия выполняются, мы увеличиваем счетчик подходящих пар и обновляем максимальную сумму чисел для таких пар.

В конце работы программы выводим количество подходящих пар и максимальную сумму.

Давайте разберем код построчно:
with open('17.txt', 'r') as f:
    nums = []
    max_three_digit = -1
    for num in f:
        num = int(num)
        nums.append(num)
        if 100 <= num <= 999:
            max_three_digit = max(max_three_digit, num)

cnt = 0
total = 0

# Обход всех пар чисел в списке
for i in range(len(nums) - 1):
    left, right = nums[i], nums[i + 1]
    
    # Проверка условий для пары и обновление счетчика и максимальной суммы
    if (100 <= left <= 999) != (100 <= right <= 999) and left + right >= max_three_digit:
        cnt += 1
        total = max(total, left + right)

print(cnt, total)
Ответ: 1657 10962
L. задача 19 лёгкая

Два игрока, Алиса и Боб, играют в игру с кучей монет. Алиса ходит первой.

За один ход игрок может либо добавить одну монету в кучу, либо утроить количество монет в куче.

Игра завершается, когда в куче становится 200 или больше монет.

Победителем считается игрок, сделавший последний ход. В начальный момент в куче M монет, 1 ≤ M < 200.

Найдите минимальное значение M, при котором Алиса не может выиграть за один ход, но при любом ходе Алисы Боб может выиграть своим первым ходом.
Решение
1 вариант

Для решения этой задачи мы используем рекурсивную функцию, чтобы исследовать все возможные ходы игры для Боба и Алисы.

Функция принимает два аргумента: текущее количество камней и номер хода.

С помощью рекурсии просчитаем все варианты развития игры.

В каждый ход мы должны понимать:
  • сколько камней в куче
  • чей сейчас ход.

Чей ход будем определять по номеру хода:

  1. начало игры
  2. Алиса
  3. Боб
  4. и т. д.
Схема
  1. В первую очередь мы проверяем, можно ли победить на текущем ходу. Если да, и это первый ход Боба, то возвращаем истину.
  2. Если на первый ход Боба победа невозможна, а ходы идут дальше, возвращаем ложь.
  3. Далее, мы рассматриваем два варианта хода: увеличить количество монет на 1 или увеличить его в 3 раза.
    • Когда ходит Алиса, для победы Боба нужно, чтобы он мог победить при любом ходе Алисы (используем and).
    • Когда ходит Боб, он выбирает ход, который приведет его к победе (используем or).

В конце, мы перебираем все стартовые позиции и ищем первую, при которой Боб может выиграть.

Давайте разберем код построчно:
# функция проверит, можно ли победить на текущем ходе
def task_19(stones, current_move):
    # Нам подходит только один вариант, когда Боб победил на своём первом ходе
    if stones > 199:
        # Если это первый ход Боба, то вернем истину
        if current_move == 2:
            return True
        # Если же это ход Алисы или более поздний ход Боба, то мы возвращаем False
        else:
            return False
    # если на свой первый ход Боб не победил,
    # То возвращаем False - такой вариант не подходит  
    if current_move >= 2:
        return False
    
    # Есть 2 варианта хода
    # Увеличиваем количество камней на 1 и ход на 1
    first = task_19(stones + 1, current_move + 1)
    # Увеличиваем количество камней в 3 раза и ход на 1
    second = task_19(stones * 3, current_move + 1)

    # Когда ходит Алиса, Боб должен победить при любой игре Алисы. используем and
    # Когда ходит Боб, то мы можем взять любой из ходов Боба, так как он играет оптимально.
    # используем or
    # с учётом условий выше, current_move к этому моменту может равняться только 0 или 1
    if current_move == 0:
        return first and second
    else:
        return first or second

# переберём все варианты стартовой позиции
# выведем первое (минимальное) число, которое нам подойдёт
for i in range(1, 199 + 1):
    if task_19(i, 0):
        print(i)
        break
2 вариант

Во втором варианте решения этой задачи мы используем рекурсивную функцию f(s,m), которая проверяет, может ли текущий игрок выиграть при данном состоянии игры. Здесь s — это текущее количество монет, а m — это номер хода.

  1. Сначала проверяем, есть ли уже 200 или больше монет в куче. Если да, то выигрывает игрок, который сделал последний ход.
  2. Если ходов больше нет, то никто не выиграл, и функция возвращает 0.
  3. Затем мы рассматриваем два возможных хода: добавить одну монету или утроить текущее количество монет. Для каждого хода рекурсивно проверяем, может ли текущий игрок выиграть.
    • Если сейчас ход Боба, ему достаточно одного выигрышного хода (используем any).
    • Если сейчас ход Алисы, то Боб должен выиграть при любом её ходе (используем all).

В конце, мы перебираем все стартовые позиции от 1 до 199 и ищем те, при которых Боб может выиграть, играя вторым.

Давайте разберем код построчно:
# Функция f(s, m) проверяет, может ли игрок выиграть при текущем состоянии игры
def f(s, m):
    if s > 199:  # Если в куче уже 200 или больше монет
        return m % 2 == 0  # Побеждает тот, кто сделал последний ход
    if m == 0:  # Если ходов больше нет
        return 0  # Никто не выиграл
    # Проверяем возможные ходы: добавить одну монету или утроить количество монет
    h = [f(s + 1, m - 1), f(s * 3, m - 1)]
    # В зависимости от того, чей сейчас ход, проверяем, может ли этот игрок выиграть
    return any(h) if (m - 1) % 2 == 0 else all(h)

# Находим все такие M, при которых Боб может выиграть, играя вторым
print(' '.join(map(str, [s for s in range(1, 200) if f(s, 2)])))
Ответ: 66
M. задача 20 лёгкая

Два игрока, Алиса и Боб, играют в игру с кучей монет. Алиса ходит первой.

За один ход игрок может либо добавить одну монету в кучу, либо утроить количество монет в куче.

Игра завершается, когда в куче становится 200 или больше монет.

Победителем считается игрок, сделавший последний ход. В начальный момент в куче M монет, 1 ≤ M < 200.

Найдите два наименьших значения M, при которых у Алисы есть выигрышная стратегия, причём одновременно выполняются два условия:

  1. Алиса не может выиграть за один ход;
  2. Алиса может выиграть своим вторым ходом независимо от того, как будет ходить Боб.

Найденные значения запишите в ответе в порядке возрастания в одну строку через пробел.

Решение
1 вариант
Расширим код предыдущей задачи. Мы теперь болеем за Алису, ей нужно победить на свой второй ход.
Схема
Изменим код учитывая новые условия:
# функция проверит, можно ли победить на текущем ходе
def task_20(stones, current_move):
    if stones > 199:
        # Если это второй ход Боба, то вернем истину
        if current_move == 3:
            return True
        # Если же это ход Алисы или другой ход Боба, то мы возвращаем False
        else:
            return False
    # если на свой второй ход Боб не победил,
    # То возвращаем False - такой вариант не подходит  
    if current_move >= 3:
        return False
    
    # Есть 2 варианта хода
    # Увеличиваем количество камней на 1 и ход на 1
    first = task_20(stones + 1, current_move + 1)
    # Увеличиваем количество камней в 3 раза и ход на 1
    second = task_20(stones * 3, current_move + 1)

    # Ходы Боба и Алисы чередуются. Чей ход можно определять по чётности хода
    # теперь болеем за Боба, поэтому поменяем местами and и or
    if current_move % 2 == 0:
        return first or second
    else:
        return first and second

# переберём все варианты стартовой позиции
# выведем все подходящие числа
for i in range(1, 199 + 1):
    if task_20(i, 0):
        print(i, end=' ')

2 вариант

Мы меняем фокус на Алису.

Теперь ищем стартовые позиции s, при которых Алиса не может выиграть за один ход, но может выиграть своим вторым ходом. Это мы можем сделать добавив дополнительную проверку, чтобы удостовериться, что Алиса не выигрывает на первом ходу, но выигрывает на втором.
Давайте разберем код построчно:
# Функция f(s, m) проверяет, может ли игрок выиграть при текущем состоянии игры
def f(s, m):
    if s > 199:  # Если в куче уже 200 или больше монет
        return m % 2 == 0  # Побеждает тот, кто сделал последний ход
    if m == 0:  # Если ходов больше нет
        return 0  # Никто не выиграл
    # Проверяем возможные ходы: добавить одну монету или утроить количество монет
    h = [f(s + 1, m - 1), f(s * 3, m - 1)]
    # В зависимости от того, чей сейчас ход, проверяем, может ли этот игрок выиграть
    return any(h) if (m - 1) % 2 == 0 else all(h)

# Находим все такие M, при которых Алиса не может выиграть за один ход, 
# но может выиграть своим вторым ходом
print(' '.join(map(str, [s for s in range(1, 200) if not f(s, 1) and f(s, 3)])))
Ответ: 22 65
N. задача 21 лёгкая
Два игрока, Алиса и Боб, играют в игру с кучей монет. Алиса ходит первой.

За один ход игрок может либо добавить одну монету в кучу, либо утроить количество монет в куче.

Игра завершается, когда в куче становится 200 или больше монет.

Победителем считается игрок, сделавший последний ход. В начальный момент в куче M монет, 1 ≤ M < 200.

Найдите минимальное значение M, при котором одновременно выполняются два условия:

  1. У Боба есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Алисы;
  2. У Боба нет стратегии, которая позволит ему гарантированно выиграть первым ходом.

Если найдено несколько значений M, в ответе запишите минимальное из них.

Решение
1 вариант

Расширим код предыдущей задачи.

Снова болеем за Боба, но тут более хитрая схема.

Бобу нельзя победить именно своим первым ходом, добавим это в условие перебора.

Используем функцию из задания 19.
# функция проверит, можно ли победить на текущем ходе
def task_21(stones, current_move):
    if stones > 199:
        # Если это первый или второй ход Боба, то вернем истину
        if current_move in [2, 4]:
            return True
        # Если же это ход Алисы или другой ход Боба, то мы возвращаем False
        else:
            return False
    # если на свой второй ход Боб не победил,
    # То возвращаем False - такой вариант не подходит  
    if current_move >= 4:
        return False
    
    # Есть 2 варианта хода
    # Увеличиваем количество камней на 1 и ход на 1
    first = task_21(stones + 1, current_move + 1)
    # Увеличиваем количество камней в 3 раза и ход на 1
    second = task_21(stones * 3, current_move + 1)

    # Ходы Алисы и Боба чередуются. Чей ход можно определять по чётности хода
    # снова болеем за Боба, поэтому поменяем местами and и or
    if current_move % 2 == 0:
        return first and second
    else:
        return first or second

# переберём все варианты стартовой позиции
# выведем все подходящие числа
for i in range(1, 199 + 1):
    if task_21(i, 0) and not task_19(i, 0):
        print(i)
        break
2 вариант
Здесь мы ищем стартовые позиции s, при которых Боб не может выиграть на своём первом ходу, делая ход вторым (то есть на втором ходу игры), но может выиграть на своём втором ходу, делая ход вторым (то есть на четвёртом ходу игры). Это выражается как not f(s,2) and f(s,4).
Давайте разберем код построчно:
# Функция f(s, m) проверяет, может ли игрок выиграть при текущем состоянии игры
def f(s, m):
    if s > 199:  # Если в куче уже 200 или больше монет
        return m % 2 == 0  # Побеждает тот, кто сделал последний ход
    if m == 0:  # Если ходов больше нет
        return 0  # Никто не выиграл
    # Проверяем возможные ходы: добавить одну монету или утроить количество монет
    h = [f(s + 1, m - 1), f(s * 3, m - 1)]
    # В зависимости от того, чей сейчас ход, проверяем, может ли этот игрок выиграть
    return any(h) if (m - 1) % 2 == 0 else all(h)

# Находим все такие M, при которых Боб не может выиграть за свой первый ход, 
# но может выиграть своим вторым ходом
print(' '.join(map(str, [s for s in range(1, 200) if not f(s, 2) and f(s, 4)])))
Ответ: 64
O. задача 22 лёгкая
В файле 22.txt содержится информация о совокупности N вычислительных процессов, которые могут выполняться параллельно или последовательно. Будем говорить, что процесс B зависит от процесса A, если для выполнения процесса B необходимы результаты выполнения процесса A. В этом случае процессы могут выполняться только последовательно.

Информация о процессах представлена в виде txt файла.

В первом столбце указан идентификатор процесса (ID), во втором столбце — время его выполнения в миллисекундах, в третьем столбце перечислены с разделителем «;» ID процессов, от которых зависит данный процесс. Если процесс является независимым, то указано значение 0.

Вот первые строки файла 22.txt:
1 200 0
2 220 0
3 250 1;2
4 280 3
5 110 4
файл 22.txt можно открыть используя open()
Определите минимальное время, через которое завершится выполнение всей совокупности процессов, при условии, что все независимые друг от друга процессы могут выполняться параллельно.
Решение
Для решения этой задачи мы используем словарь для хранения минимального времени выполнения каждого процесса.

Изначально в этом словаре есть только начальный процесс с временем выполнения равным нулю.

Мы также создаём список, в который считываем все данные о процессах и их зависимостях.

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

В конце программы мы выводим максимальное из найденных минимальных времен выполнения.

Давайте разберем код построчно:
d = {'0': 0}  # Словарь для хранения минимального времени выполнения для каждого процесса
data = []  # Список для хранения информации о каждом процессе

# Чтение данных из файла и преобразование их в удобный для работы формат
for s in open('22.txt'):
    data.append(s.replace(';', ' ').split())

# Цикл, который будет выполняться до тех пор, пока для всех процессов не будет найдено минимальное время выполнения
while len(d) != len(data) + 1:
    for s in data:
        # Проверка, известно ли минимальное время выполнения для всех зависимостей текущего процесса
        if all(sub in d for sub in s[2:]):
            # Вычисление и сохранение минимального времени выполнения для текущего процесса
            d[s[0]] = int(s[1]) + max(d[sub] for sub in s[2:])

# Вывод максимального значения среди всех минимальных времен выполнения процессов
print(max(d.values()))
Ответ: 2670
P. задача 23 лёгкая
Исполнитель преобразует число на экране. У исполнителя есть две команды, которые обозначены латинскими буквами:

  1. Вычесть 2
  2. Найти целую часть от деления на 2

Программа для исполнителя — это последовательность команд.

Сколько существует программ, для которых при исходном числе 31 результатом является число 2?
Траектория вычислений программы — это последовательность результатов выполнения всех команд программы.

Например, для программы АBBA при исходном числе 1972 траектория будет состоять из чисел 1970, 985, 492, 490.

Решение
Для решения этой задачи мы используем рекурсивный подход.

Исходная функция принимает один аргумент x, который обозначает текущую позицию. Нашей целью является вычисление количества различных путей для достижения заданной точки y из исходной точки x, двигаясь по определенным правилам (вычитание 2 или деление на 2).

Если x<2, то мы уже не можем достичь точки y по заданным правилам, и возвращаем 0. Если x равен y, это означает, что мы достигли целевой точки, и возвращаем 1.

В противном случае мы рекурсивно вызываем функцию два раза: один раз для x−2 и один раз для x//2, а затем складываем полученные результаты. Это даст нам общее количество путей для достижения y из x.

В конце программы мы вызываем эту функцию с исходной точкой x=31 и выводим полученный результат.

Давайте разберем код построчно:
def f(x):
    # Если x меньше 2, мы проскочили нужную точку
    if x < 2:
        return 0
    # если попали, то такой путь подходит
    if x == y:
        return 1
    # считаем количества путей для обоих действий
    return f(x - 2, y) + f(x // 2, y)


# Вызываем функцию для исходной точки
print(f(31))
Ответ: 51
Q. задача 24 лёгкая
Текстовый файл 24.txt состоит из символов A, B, C, D, E.
Определите максимальное число идущих подряд символов в файле, среди которых нет символов AB, идущих подряд.
Для выполнения этого задания следует написать программу.
Начало файла 24.txt
CDBABBEBEBEBABDCAECCC...
файл 24.txt можно открыть используя open()
Решение
1 вариант
Для решения этой задачи мы используем следующий подход:
  1. Открываем файл и читаем его содержимое в строку.
  2. Инициализируем две переменные: одну для хранения максимальной длины подстроки и одну для хранения текущей длины подстроки.
  3. Затем, проходим по каждому символу в строке, проверяя наличие нежелательной подстроки «AB».
  4. Если в текущем сегменте строки находим запрещенную подстроку, сравниваем текущую длину с максимальной и, при необходимости, обновляем максимальную длину. После этого сбрасываем текущую длину до 1.
  5. Если запрещенная подстрока не найдена, просто увеличиваем текущую длину на 1.
  6. В конце работы алгоритма сравниваем текущую длину с максимальной еще раз, чтобы учесть последний сегмент строки.
Таким образом, мы найдем максимальную длину подстроки, не содержащей «AB», и выведем её.
Давайте разберем код построчно:
# Открываем файл "24.txt" для чтения
with open("24.txt", "r") as file:
    # Читаем всё содержимое файла в строку file_content
    file_content = file.read()

# Инициализируем переменные для хранения максимальной и текущей длины подстроки
max_length = 0
current_length = 1

# Задаем подстроку, которая не должна присутствовать в искомой подстроке
substring = "AB"

# Проходим по каждому символу в строке
for i in range(len(file_content)):
    # Проверяем, содержится ли запрещенная подстрока в текущем сегменте
    if file_content[i:i + len(substring)] == substring:
        # Если текущая длина больше максимальной, обновляем максимальную длину
        max_length = max(max_length, current_length)
        # Сбрасываем текущую длину
        current_length = 1
    else:
        # Увеличиваем текущую длину подстроки
        current_length += 1

# Проверяем последний сегмент строки
max_length = max(max_length, current_length)

# Выводим максимальную длину подстроки
print(max_length)
2 вариант
Для решения этой задачи мы используем следующий подход:
  1. Сначала мы открываем файл для чтения и сохраняем его содержимое в строку.
  2. Далее, мы заменяем все вхождения «AB» на «A B», добавляя пробел между «A» и «B». Это нужно для того, чтобы избавиться от последовательностей «AB» в строке.
  3. После этого, мы разбиваем измененную строку на подстроки, разделенные пробелами. Теперь в каждой подстроке не будет последовательностей «AB».
  4. В конце, мы находим подстроку с максимальной длиной и выводим её длину.
# Открываем файл '24.txt' для чтения
with open("24.txt", "r") as file:
    # Читаем все содержимое файла в строку file_content
    file_content = file.read()

# Ставим между AB пробел, чтобы дальше разделить их на подстроки, где не содержаться подряд идущие символы AB
s = file_content.replace("AB", "A B")

# Разбиваем полученную строку на подстроки
# Теперь в списке s хранятся подстроки, в которых нет подряд идущих символов "AB"
s = s.split()
# Находим подстроку максимальной длинны
print(len(max(s, key=len))))
Ответ: 196
R. задача 25 лёгкая
Рассматриваются числа, которые имеют ровно четыре различных натуральных делителя, не считая единицы и самого числа.

Примером такого числа является число 12, его делители: 2, 3, 4, 6.

Напишите программу, которая будет находить и выводить в порядке возрастания пять таких минимальных чисел, которые больше числа 123456.
Для каждого найденного числа нужно вывести это число, затем, через пробел, вывести сумму его делителей.

Например, для числа 12 нужно вывести строку 12 15.

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

Решение
Для решения этой задачи мы используем следующий подход:
  1. Сначала создаем функцию для нахождения всех уникальных делителей данного числа. В этой функции используем цикл, который проходит от 2 до квадратного корня из числа. Если число делится нацело, добавляем оба делителя в множество.

    Почему до квадратного корня спросите вы? Давайте разберемся. Допустим, у нас есть число 36, и нам нужно найти все его делители. Делители 36 это: 1, 2, 3, 4, 6, 9, 12, 18, 36.

    Квадратный корень из 36 равен 6. Заметьте, что все делители, которые меньше или равны 6 (1, 2, 3, 4, 6), можно умножить на другое число, чтобы получить 36:
    • 1 × 36 = 36
    • 2 × 18 = 36
    • 3 × 12 = 36
    • 4 × 9 = 36
    • 6 × 6 = 36

    Как видите, каждый делитель меньше или равен 6 имеет «пару» среди делителей, которая больше или равна 6. Иными словами, нам не нужно проверять числа больше 6, чтобы найти все делители 36 — мы можем просто найти меньшие делители и поделить 36 на них, чтобы получить большие делители.

    Этот принцип работает для любого числа, не только для 36, и позволяет существенно ускорить поиск делителей.

  2. Далее задаем начальное значение числа, с которого начнем поиск, и счетчик для подсчета количества найденных подходящих чисел.
  3. Используем цикл while, в котором увеличиваем значение текущего числа и ищем его делители с помощью созданной функции.
  4. Проверяем, имеет ли текущее число ровно 4 делителя. Если да, выводим это число и сумму его делителей, а также увеличиваем счетчик найденных чисел.
  5. Продолжаем поиск, пока не найдем пять таких чисел.

Таким образом, у нас есть цикл, который перебирает числа и проверяет количество их делителей, и мы продолжаем этот процесс до тех пор, пока не найдем нужное количество подходящих чисел.

Давайте разберем код построчно:
# Функция, которая находит все делители числа n
def find_divisors(n):
    divisors = set()  # Используем множество для хранения уникальных делителей
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            divisors.add(i)
            divisors.add(n // i)  # Добавляем оба делителя: i и n // i
    return divisors

# Начальное значение числа, с которого начнется поиск
start_number = 123456

# Счетчик для отслеживания количества найденных подходящих чисел
count_found = 0

while count_found < 5:  # Ищем пока не найдем пять подходящих чисел
    start_number += 1  # Переходим к следующему числу
    divisors = find_divisors(start_number)  # Ищем делители числа
    # Если у числа ровно 4 делителя
    if len(divisors) == 4:
        # Выводим число и сумму его делителей
        print(start_number, sum(divisors))
        # Увеличиваем счетчик
        count_found += 1
Ответ:
123476 92613
123484 92619
123489 54896
123507 54904
123524 92649
S. задача 26 лёгкая

Татьяна участвует в соревновании по программированию. Соревнование продолжается ровно t минут и содержит n задач.

Участнику нужно решить как можно больше задач из предложенных, а при равном числе решённых задач учитывается штрафное время (чем меньше — тем лучше).

Штрафное время равно сумме времён, прошедших с начала соревнования, когда была сдана каждая из решённых участником задач.

  • Татьяна моментально прочитала условия всех задач и поняла про каждую задачу, сколько времени нужно для её решения.
  • Татьяна тратит время только на решение задач, решив одну задачу она сразу же переходит к другой.
Определите, какое максимальное число задач сможет решить Татьяна и какой минимальное штрафное время она получит.
Входные данные.
  • Первая строка входного файла 26.txt содержит число t, 1 ≤ t ≤ 10 6 продолжительность соревнования.
  • Во второй строке записано число n, 1 ≤ n ≤ 1000 количество задач в соревновании.
  • Следующие n строк содержат по одному целому число — время, необходимое для решения этой задачи.

Программа должна вывести два числа — максимальное число задач, которое может решить Татьяна за соревнование и минимальное суммарное штрафное время, которое она получит.

Например, пусть программа получает следующие входные данные:
50
3
20
10
30
файл 26.txt можно открыть используя open()
Это означает, что соревнование продолжается 50 минут, и на этом соревновании предлагается 3 задачи. Татьяна сначала решит задачу за 10 минут (штраф будет равен 10), потом задачу за 20 минут (штраф будет равен 30, т. к. эта задача будет сдана через 30 минут после начала тура). Суммарный штраф будет равен 40. Третью задачу Татьяна решить не успеет.

Ответ на этот пример: 2 40.

Решение
Для решения этой задачи мы используем следующий подход:
  1. Сначала сортируем задачи по времени, необходимому для их решения, в порядке возрастания. Это делается для того, чтобы Татьяна сначала решала наиболее быстрые задачи.
  2. Затем инициализируем переменные для отслеживания общего потраченного времени, штрафного времени и количества решенных задач.
  3. Проходим по отсортированному списку задач. Для каждой задачи проверяем, можем ли мы её решить в рамках оставшегося времени.
  4. Если можем, то учитываем время решения этой задачи в общем времени и штрафном времени, а также увеличиваем счетчик решенных задач.
  5. Если сталкиваемся с задачей, которую решить уже невозможно из-за ограничения по времени, прерываем цикл.

В результате, мы получаем количество решенных задач и штрафное время, которое возвращаем как ответ на задачу.

Давайте разберем код построчно:
def solve_competition_problem(t, n, tasks_time):
    # Сортируем время, требующееся для решения задач, в порядке возрастания
    tasks_time.sort()
    
    # total_time - общее время, потраченное на решение задач
    # penalty_time - штрафное время
    # solved_tasks - количество решенных задач
    total_time = 0
    penalty_time = 0
    solved_tasks = 0
    
    # Проходим по списку задач
    for task_time in tasks_time:
        # Если Татьяна может решить текущую задачу в рамках оставшегося времени
        if total_time + task_time <= t:
            # Увеличиваем общее время на время текущей задачи
            total_time += task_time
            # Учитываем штрафное время для текущей задачи
            penalty_time += total_time
            # Увеличиваем счетчик решенных задач
            solved_tasks += 1
        else:
            # Если текущую задачу решить невозможно, прерываем цикл
            break
    
    # Возвращаем количество решенных задач и штрафное время
    return solved_tasks, penalty_time

# Читаем данные из файла
with open("26.txt", 'r') as file:
    t = int(file.readline().strip())  # Продолжительность соревнования
    n = int(file.readline().strip())  # Количество задач
    tasks_time = [int(file.readline().strip()) for _ in range(n)]  # Время на решение каждой задачи

# Решаем задачу и выводим результат
print(*solve_competition_problem(t, n, tasks_time))
Ответ: 124 635141
T. 27 задача A лёгкая

На вход программе подается последовательность из N целых положительных чисел. Рассматриваются все пары различных элементов последовательности (элементы пары не обязаны стоять в последовательности рядом, порядок элементов в паре не важен). Необходимо найти такую пару чисел, произведение которых будет кратно 77 и при этом будет максимальным.

Программа должна напечатать одно число — максимально возможное произведение, соответствующее условиям задачи.

Входные данные.
Дан входной файл 27_A.txt. В первой строке файла указывается количество обрабатываемых значений N. В каждой из следующих N строк записано одно обрабатываемое число x.
Пример входных данных:
6
700
100
1100
87
43
28
файл 27_A.txt можно открыть используя open()
Для указанного примера входных данных искомая пара — 700, 1100. Соответствующее ей произведение — 770_000.
В ответе укажите значение искомого произведения для файла 27_A.txt
Решение
Для решения этой задачи мы используем следующий подход:
  1. Сначала открываем файл и читаем все числа в список, при этом первое число из файла сохраняем в отдельной переменной, так как оно указывает на количество чисел в списке.
  2. Инициализируем переменную для хранения максимального произведения чисел, которое должно быть кратно 77.
  3. Затем используем два вложенных цикла для перебора всех возможных пар чисел в списке.
  4. Для каждой пары чисел вычисляем их произведение.
  5. Проверяем, является ли это произведение кратным 77 и больше ли оно текущего максимального произведения.
  6. Если оба условия выполняются, обновляем значение максимального произведения.

Таким образом, после завершения всех итераций циклов, в переменной будет храниться максимальное произведение чисел, кратное 77, и это значение мы выводим.

Давайте разберем код построчно:
# Открываем файл '27-1a.txt' для чтения и загружаем все числа в список nums, а переменную n устанавливаем в первое число из файла
f_name = '27-1a.txt'
with open(f_name) as f:
    n, *nums = [int(x) for x in f]

# Инициализируем переменную prod_max, в которой будет храниться максимальное произведение чисел, кратное 77
prod_max = 0

# Два вложенных цикла, которые перебирают все пары чисел в списке nums
for left in range(n):  # Перебор для левого числа в паре
    for right in range(left + 1, n):  # Перебор для правого числа в паре, начиная с индекса, следующего за left
        # Вычисляем произведение текущей пары чисел
        prod = nums[left] * nums[right]
        
        # Проверяем, делится ли произведение на 77 и больше ли оно текущего максимального произведения
        if prod % 77 == 0 and prod > prod_max:
            # Обновляем максимальное произведение
            prod_max = prod
            
# Выводим значение максимального произведения
print(prod_max)
Ответ: 99370810
U. 27 задача B лёгкая

На вход программе подается последовательность из N целых положительных чисел. Рассматриваются все пары различных элементов последовательности (элементы пары не обязаны стоять в последовательности рядом, порядок элементов в паре не важен). Необходимо найти такую пару чисел, произведение которых будет кратно 77 и при этом будет максимальным.

Программа должна напечатать одно число — максимально возможное произведение, соответствующее условиям задачи.

Входные данные.
Дан входной файл 27_B.txt. В первой строке файла указывается количество обрабатываемых значений N. В каждой из следующих N строк записано одно обрабатываемое число x.
Пример входных данных:
6
700
100
1100
87
43
28
файл 27_B.txt можно открыть используя open()
Для указанного примера входных данных искомая пара — 700, 1100. Соответствующее ей произведение — 770_000.
В ответе укажите значение искомого произведения для файла 27_B.txt
Предупреждение:
для обработки файла 27_B.txt не следует использовать переборный алгоритм, вычисляющий сумму для всех возможных вариантов, поскольку написанная по такому алгоритму программа будет выполняться слишком долго.
Решение
Для решения этой задачи мы используем несколько ключевых идей:
  1. Поиск максимальных чисел: Сначала нам нужно найти наибольшие числа в списке, которые удовлетворяют определенным условиям (наибольшее число вообще, наибольшее число кратное 77, наибольшее число кратное 7 и наибольшее число кратное 11). Мы можем сделать это, пройдясь по всем числам списка один раз и обновляя наши «рекордные» числа по мере необходимости.
  2. Сравнение кандидатов на максимальное произведение: После того, как у нас есть все эти максимальные числа, мы можем рассмотреть два варианта максимального произведения:
    • Произведение наибольшего числа (не кратного 77) и наибольшего числа, кратного 77.
    • Произведение наибольшего числа, кратного 7, и наибольшего числа, кратного 11.
  3. Выбор лучшего варианта: Наконец, мы сравниваем эти два варианта произведения и выбираем наибольший.

Этот алгоритм оптимизирован: вместо полного перебора всех пар чисел (как в первом решении) здесь используются только максимальные значения для определённых условий, что сильно ускоряет работу программы.

Давайте разберем код построчно:
# Открываем файл '27-1b.txt' для чтения и загружаем все числа в список nums, а переменную n устанавливаем в первое число из файла
f_name = '27-1b.txt'
with open(f_name) as f:
    n, *nums = [int(x) for x in f]

# Инициализация переменных для хранения максимальных чисел, удовлетворяющих различным условиям
max_1 = 0  # самое большое число
max_2 = 0  # второе по величине число
max_77 = 0  # максимальное число, кратное 77
max_7 = 0   # максимальное число, кратное 7
max_11 = 0  # максимальное число, кратное 11

# Перебор всех чисел из списка nums
for i in range(n):
    # Обновление max_1 и max_2 (два наибольших числа в списке)
    _, max_2, max_1 = sorted([nums[i], max_2, max_1])
    
    # Обновление max_77, max_7 и max_11 в зависимости от кратности текущего числа
    if nums[i] % 77 == 0:
        max_77 = max(max_77, nums[i])
    elif nums[i] % 7 == 0:
        max_7 = max(max_7, nums[i])
    elif nums[i] % 11 == 0:
        max_11 = max(max_11, nums[i])

# Вывод текущих значений максимальных переменных (для отладки)
print(max_1, max_2, max_77, max_7, max_11)

# Вычисление двух возможных максимальных произведений
if max_1 != max_77:
    v1 = max_1 * max_77
else:
    v1 = max_2 * max_77
v2 = max_7 * max_11

# Вывод результата
print(v1, v2)
print(max(v1, v2))
Ответ: 902491450014
Fri Feb 09 2024 12:47:47 GMT+0300 (Moscow Standard Time)