№24
Основная волна 2026
Обработка символьных строк
Основная волна 2026
Условие
Текстовый файл состоит не более чем из 106 символов и содержит только десятичные цифры, а также знаки «+» и «*» (сложения и умножения). Определите максимальное количество символов в непрерывной последовательности, являющейся корректным арифметическим выражением с целыми неотрицательными числами (без знака). В этом выражении никакие два знака арифметических операций не стоят рядом. В записи чисел отсутствуют незначащие (ведущие) нули. В ответе укажите количество символов в найденном выражении.
Ответ: 259
Разбор двух решений
Оба варианта ищут длину самой длинной подстроки, которая является корректным арифметическим выражением: числа записаны без ведущих нулей, между числами стоят + или *, выражение содержит хотя бы одну операцию.
Правила для числа:
- либо одна цифра
0; - либо число начинается с
1–9, дальше любые цифры (12,305, но не07, не012).
Правила для выражения:
- схема:
число (оператор число)+— то есть минимум5+3, одно число без операции не подходит; - операторы — только
+и*.
Вариант 1 — регулярное выражение
import re
s = open('24.txt').readline()
num = '([1-9][0-9]*|0)'
pat = f'{num}([+*]{num})+'
res = 0
for sub in re.finditer(pat, s):
res = max(res, len(sub[0]))
print(res)
Шаблон числа ([1-9][0-9]*|0) — либо число без ведущего нуля (5, 12, 100), либо отдельный ноль.
Полный шаблон число([+*]число)+ — число, затем один или больше фрагментов «оператор + число». Подходят: 0+5, 12*3+0, 7+8*9+1. Не подходят: 05+3 (ведущий ноль), 5++3 (два оператора подряд), 5 (нет операции).
re.finditer находит все вхождения шаблона, в том числе пересекающиеся. Среди найденных подстрок берётся максимальная длина.
Идея: явно описываем условие задачи на языке регулярных выражений и перебираем все подходящие куски. Плюс — код короткий и читается почти как формулировка задачи.
Вариант 2 — метод замен
s = open('24.txt').readline()
s = s.replace('*','+')
for x in '123456789': s = s.replace(x, '1')
while '++' in s or '+01' in s or '+00' in s:
s = s.replace('++', '+ +').replace('+01', '+0 1').replace('+00', '+0 0')
mx = 0
for sub in s.split():
sub = sub.strip('+')
mx = max(mx, len(sub))
print(mx)
Шаг 1. Заменяем * на + — для длины подстроки знаки операций не важны.
Шаг 2. Цифры 1–9 заменяем на 1 — конкретные значения цифр на длину не влияют (847 и 111 — по три символа).
Шаг 3. Цикл while вставляет пробелы в «плохих» местах и разрывает выражение:
++→+ +— два оператора подряд;+01→+0 1— число с ведущим нулем после оператора;+00→+0 0— число00недопустимо.
Шаг 4. split() режет строку по пробелам, strip('+') убирает лишние + по краям. Длина самого длинного фрагмента — ответ.
Идея: вместо описания «как должно выглядеть правильно» помечаем всё неправильное и режем там, где правила нарушены.
Сравнение подходов
| Регулярки | Метод замен | |
|---|---|---|
| Суть | «Ищем всё, что подходит под шаблон» | «Режем всё, что не подходит» |
| Инструмент | re.finditer | replace + split |
| Надёжность | шаблон = точное условие | важно не забыть ни одну «плохую» пару |
Оба метода для этой задачи дают один ответ — 259.