Подготовка к школе
1 класс
2 класс
3 класс
4 класс
5 класс
6 класс
7 класс
8 класс
9 класс
10 класс
11 класс
ОГЭ
ЕГЭ
Для всех
Назад

24. Подсчет символов: #297615

Сообщить о проблеме
Задание #297615
Задание было решено верно
Задание было решено неверно

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

В ответе укажите количество символов.

Корректное выражение — это число, за которым идёт любое количество пар «знак операции плюс число». Число — либо одиночный $0$, либо цифра из $7$–$9$, за которой идут любые цифры набора $0$, $7$, $8$, $9$. Запрет ведущих нулей означает ровно одно: с нуля может начинаться только само число $0$.

Знаков в этом файле очень много — почти треть всех символов, и они часто идут по два-три подряд. Поэтому длинных выражений здесь не бывает, каждая пара соседних знаков рвёт цепочку.

Помним про подстроку: фрагмент имеет право начаться в середине блока цифр, отбросив ведущие нули. Но у обрезанного старта есть плата — продолжить его влево знаком операции нельзя, слева стоит цифра. Присоединять что-то слева можно только когда число начинается с самого начала своего блока цифр. Это и отражает переменная chain.

Идём слева направо и для каждой позиции $j$ с цифрой считаем $L[j]$ — длину самого длинного корректного выражения, кончающегося в этой позиции. Вариантов два: либо это одно число, либо к числу слева через знак операции приклеивается уже посчитанное выражение, кончавшееся на два символа левее начала числа.

s = open('24-21.txt').read().strip()
n = len(s)
ops = set('-*')

L = [0] * n          # L[j] — длина макс. верного выражения, кончающегося в j
best = 0
r = 0                # начало текущего блока цифр

for j in range(n):
    if s[j] in ops:
        r = j + 1
        continue

    # 1) выражение из одного числа
    if s[r] != '0':                     # блок начинается со значащей цифры
        cur = j - r + 1
        chain = r
    elif j == r:                        # само число 0
        cur = 1
        chain = r
    else:                               # блок начался с 0 — стартуем с первой ненулевой
        q = r
        while q <= j and s[q] == '0':
            q += 1
        cur = j - q + 1 if q <= j else 1
        chain = -1                      # слева цифра, знак операции не приписать

    # 2) приклеиваем слева выражение через знак операции
    if chain >= 2 and s[chain-1] in ops and L[chain-2] > 0:
        cur = max(cur, L[chain-2] + 1 + (j - chain + 1))

    L[j] = cur
    best = max(best, cur)

print(best)   # 111

Проверка найденного фрагмента: длина $111$, он целиком распознаётся регулярным выражением для корректной записи. Слева от него идёт $0*-$, то есть перед стартом знак, а перед ним ещё один — влево не растянуть. Справа фрагмент кончается на $0988$, а дальше $*$ и снова знак, что тоже запрещено.

Показать
Очки опыта 20
Спросить Зави
0 заданий сегодня

Предложить улучшение