№24

Основная волна 2026

Обработка символьных строк

Основная волна 2026

Условие

Текстовый файл состоит не более чем из 106 символов и содержит только десятичные цифры, а также знаки «+» и «*» (сложения и умножения). Определите максимальное количество символов в непрерывной последовательности, являющейся корректным арифметическим выражением с целыми неотрицательными числами (без знака). В этом выражении никакие два знака арифметических операций не стоят рядом. В записи чисел отсутствуют незначащие (ведущие) нули. В ответе укажите количество символов в найденном выражении.

Ответ: 259

Разбор двух решений

Оба варианта ищут длину самой длинной подстроки, которая является корректным арифметическим выражением: числа записаны без ведущих нулей, между числами стоят + или *, выражение содержит хотя бы одну операцию.

Правила для числа:

  • либо одна цифра 0;
  • либо число начинается с 19, дальше любые цифры (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. Цифры 19 заменяем на 1 — конкретные значения цифр на длину не влияют (847 и 111 — по три символа).

Шаг 3. Цикл while вставляет пробелы в «плохих» местах и разрывает выражение:

  • +++ + — два оператора подряд;
  • +01+0 1 — число с ведущим нулем после оператора;
  • +00+0 0 — число 00 недопустимо.

Шаг 4. split() режет строку по пробелам, strip('+') убирает лишние + по краям. Длина самого длинного фрагмента — ответ.

Идея: вместо описания «как должно выглядеть правильно» помечаем всё неправильное и режем там, где правила нарушены.

Сравнение подходов

РегуляркиМетод замен
Суть«Ищем всё, что подходит под шаблон»«Режем всё, что не подходит»
Инструментre.finditerreplace + split
Надёжностьшаблон = точное условиеважно не забыть ни одну «плохую» пару

Оба метода для этой задачи дают один ответ — 259.

← К списку шпаргалок