Задание 24 ЕГЭ по информатике. Обработка текста

Содержание

Теория

Открытие и чтение текстовых файлов

# Вариант 1 (классический)
f = open('24_demo.txt')
s = f.readline()          # читаем всю строку (или файл без переводов строк)
f.close()

# Вариант 2 (контекстный менеджер: файл закроется автоматически)
with open('k8.txt', 'r') as F:
    s = F.readline()

Базовые определения для задач по строкам

  • «Последовательность идущих подряд символов» = непрерывная подстрока строки s.
  • «Цепочка из одинаковых символов» = максимальный блок одного и того же символа (run).
  • «Пара/тройка» символов — соседние позиции: s[i], s[i+1] / s[i], s[i+1], s[i+2].

Типовые приёмы

  • Подсчёт максимальной длины условия “по месту” — один проход с текущим счётчиком и максимумом.
  • Непересекающиеся шаблоны — удобно заменять/помечать фрагменты, а затем считать длины между “разрывами”.
  • Поиск по алфавиту — удобно хранить строки вида 'ABC' и проверять in.

Что повторить в Python

Регулярные выражения (альтернатива ручной проверке)

import re

# Пример: найти все блоки только из 'A','B','C'
blocks = re.findall(r'[ABC]+', s)         # список всех подходящих подстрок
best = max(map(len, blocks), default=0)   # длина максимальной

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

Метод скользящих окон

Используется, когда ограничиваем количество событий в окне (например, «ровно k букв S»), а также при «запретах» на типы символов.

# Шаблон: фиксируем левую границу L, двигаем правую R,
# поддерживаем нужные счётчики и максимум длины окна.
L = 0
for R, ch in enumerate(s):
    # обновить счётчики по s[R]
    # while (условие нарушено): сузить окно слева (L += 1 и поправить счётчики)
    # обновить ответ как max(ответ, R-L+1)

Примеры решений заданий

Раздел A. Базовые задачи

A1. Максимальная длина блока, где соседние символы различны

s = open('24_demo.txt').readline()
max_cnt = cur_cnt = 1
prev = s[0]
for i in range(1, len(s)):
    if s[i] != prev:
        cur_cnt += 1
    else:
        if cur_cnt > max_cnt:
            max_cnt = cur_cnt
        cur_cnt = 1
    prev = s[i]
print(max_cnt)

A2. Максимальная цепочка из одинаковых символов: символ и длина

with open('k8.txt') as F:
    s = F.readline()
maxLen = curLen = 1
ch = s[0]
for i in range(1, len(s)):
    if s[i] == s[i-1]:
        curLen += 1
        if curLen > maxLen:
            maxLen = curLen
            ch = s[i]
    else:
        curLen = 1
print(ch, maxLen)

A3. Все цепочки максимальной длины (символ и длина для каждой)

F = open('k8.txt'); s = F.readline()
maxLen = curLen = 1
chars = [s[0]]
for i in range(1, len(s)):
    if s[i] == s[i-1]:
        curLen += 1
        if curLen == maxLen:
            chars.append(s[i])
        elif curLen > maxLen:
            maxLen = curLen
            chars = [s[i]]
    else:
        curLen = 1
for c in chars:
    print(c, maxLen)

A4. Счёт троек по правилам (алфавит B,C,D,E; ограничения на каждый символ)

s = open('k7.txt').read()
count = 0
for i in range(len(s)-2):
    if s[i] in 'BCD' and s[i+1] in 'BDE' and s[i+2] in 'BCE' and s[i] != s[i+1] and s[i+1] != s[i+2]:
        count += 1
print(count)

A5. Максимальная цепочка вида EAB EAB … (последний фрагмент может быть неполным)

s = open('k7.txt').read()
cnt = best = 0
for ch in s:
    ok = (ch == 'E' and cnt % 3 == 0) or (ch == 'A' and cnt % 3 == 1) or (ch == 'B' and cnt % 3 == 2)
    if ok:
        cnt += 1
        if cnt > best: best = cnt
    elif ch == 'E':
        cnt = 1
    else:
        cnt = 0
print(best)

A6. Максимальная длина подстроки только из A, B или C

s = open('k7.txt').read()
cnt = best = 0
for ch in s:
    if ch in 'ABC':
        cnt += 1
        if cnt > best: best = cnt
    else:
        cnt = 0
print(best)

A7. Максимальная длина цепочки из символов C

s = open('k7.txt').read()
best = cur = 0
for ch in s:
    if ch == 'C':
        cur += 1
        if cur > best: best = cur
    else:
        cur = 0
print(best)

A8. Какой символ чаще всего стоит сразу после буквы E

s = open('24.txt').read()
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
best_c, best_cnt = None, -1
for c in alphabet:
    cnt = s.count('E' + c)
    if cnt > best_cnt:
        best_cnt = cnt
        best_c = c
print(best_c)

A9. Для строк с < 25 букв A — максимальное расстояние между одинаковыми буквами

alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ans = 0
with open('inf_26_04_21_24.txt') as f:
    for line in f:
        if line.count('A') < 25: for c in alphabet: i1, i2 = line.find(c), line.rfind(c) if i1 != -1 and i2 != -1 and i2 - i1 > ans:
                    ans = i2 - i1
print(ans)

A10. Максимальная длина блока без подстроки XZZY

s = open('24_10.txt').read()
bad = 'XZZY'
L = best = 0
for R in range(len(s)):
    # сужаем окно, пока внутри есть 'XZZY'
    while s[L:R+1].find(bad) != -1:
        L += 1
    best = max(best, R - L + 1)
print(best)

Раздел B. Дополнительные задачи из этого урока

B1. 12-ричная запись, кратная 3 (максимальная длина, при равенстве — минимальное значение; вывести индекс старта)

Алфавит: цифры 0–9 и буквы A,B (равны 10,11). Кратность 3 в базе 12 определяется суммой “цифровых значений” по модулю 3. Ищем максимальные валидные блоки (только символы алфавита), а внутри — среди тех, где сумма % 3 == 0, выбираем наибольшую длину; при равенстве длины берём лексикографически/численно минимальную (в базе 12 это совпадает).

s = open('input.txt').read().strip()
val = {**{str(i): i for i in range(10)}, 'A':10, 'B':11}
def is12(ch): return ch in val

best_len, best_start, best_str = -1, -1, None
L = 0
while L < len(s):
    if not is12(s[L]): L += 1; continue
    R = L
    sm = 0
    # найдём максимально возможный блок [L..R]
    while R < len(s) and is12(s[R]): sm += val[s[R]] R += 1 # в блоке ищем наибольшую подстроку с суммой %3==0 # трюк префикс-сумм по модулю 3: храним первый индекс каждого остатка first = {0: L} # префикс нулевой длины с остатком 0 pref = 0 for i in range(L, R): pref = (pref + val[s[i]]) % 3 if pref in first: a = first[pref]; b = i+1 cand = s[a:b] cand_len = b - a if cand_len > best_len or (cand_len == best_len and (best_str is None or cand < best_str)):
                best_len, best_start, best_str = cand_len, a, cand
        else:
            first[pref] = i+1
    L = R
print(best_start)

B2. Максимальная длина корректного выражения из 6-ричных чисел и знаков «-» или «*»

Требования: без ведущих нулей (кроме самого числа 0), знаки не стоят рядом, приоритет стандартный (умножение выше вычитания), и порядок вычисления слева направо совпадает с математическим (это автоматически верно при отсутствии скобок, если фиксируем стандартный приоритет). Значит, проверяем блоки вида num (op num)*, где num — корректная 6-ричная запись.

import re
s = open('input.txt').read().strip()
# число в базе 6 без лидирующих нулей: либо "0", либо [1-5][0-5]*
num = r'(?:0|[1-5][0-5]*)'
tok = re.compile(rf'(?:{num}(?:[-*]{num})*)')

best = 0
for m in tok.finditer(s):
    best = max(best, m.end()-m.start())
print(best)

B3. Максимальная длина подстроки, где ровно 35 букв S, начинается чётной цифрой и не содержит других чётных цифр

Используем скользящее окно с подсчётом countS и запретом любых чётных цифр (кроме самой первой позиции окна). Как только в окне ровно 35 букв S — фиксируем длину.

s = open('input.txt').read().strip()
def is_even_digit(c): return c in '02468'

best = 0
L = 0
countS = 0
even_locked = False   # зафиксировано, что первая позиция была чётной цифрой
while L < len(s) and not is_even_digit(s[L]):  # сдвинем L на допустимый старт
    L += 1
R = L-1
while R+1 < len(s):
    R += 1
    c = s[R]
    if R == L:
        # первый символ должен быть чётной цифрой
        if not is_even_digit(c):
            L += 1
            while L < len(s) and not is_even_digit(s[L]): L += 1 R = L-1 countS = 0 even_locked = False continue even_locked = True else: # внутри окна запрещены чётные цифры if is_even_digit(c): # сдвигаем L за эту чётную цифру и перезапускаем окно L = R countS = 0 even_locked = False continue if c == 'S': countS += 1 # сжимаем, если S больше 35 while countS > 35:
        if s[L] == 'S': countS -= 1
        L += 1
        # первая позиция должна быть чётной цифрой
        while L <= R and not is_even_digit(s[L]):
            if s[L] == 'S': countS -= 1
            L += 1
        even_locked = (L <= R)
    if countS == 35 and L <= R:
        best = max(best, R - L + 1)
print(best)

B4. Корректное выражение из цифр, «+» и «*», значение которого равно нулю (максимальная длина)

Выражение корректно, без ведущих нулей (кроме “0”), операции не подряд. Значение ноль тогда и только тогда, когда хотя бы один сомножитель равен нулю и нет деления (его и нет), при этом сложение не обязано давать ноль — главное, что произведение какого-то множителя обнуляет итог (если структура как “сумма произведений”, то для нуля достаточно, чтобы один слагаемый был 0 и все остальные слагаемые отсутствовали; но у нас только “+” и “*”, без скобок: стандартный приоритет → выражение равно сумме произведений; сумма равна 0 ⇔ все произведения = 0). Значит, каждое произведение содержит хотя бы один множитель “0”.

import re
s = open('input.txt').read().strip()
num = r'(?:0|[1-9]\d*)'             # без ведущих нулей
term = rf'{num}(?:\*{num})*'        # произведение
expr = rf'{term}(?:\+{term})*'      # сумма произведений

best = 0
for m in re.finditer(expr, s):
    t = s[m.start():m.end()]
    # проверим, что каждое произведение в сумме имеет множитель 0
    ok = True
    for mul in t.split('+'):
        if all(f != '0' for f in mul.split('*')):
            ok = False; break
    if ok:
        best = max(best, len(t))
print(best)

B5. Максимальная длина подстроки, где пара «CD» встречается ровно 160 раз

Классическое “две точки” + подсчёт пар «CD» на лету: добавляя символ справа, увеличиваем счётчик, если образовалась новая пара; сдвигая слева — уменьшаем, если уходит пара.

s = open('input.txt').read().strip()
L = 0
cd = 0
best = 0
for R in range(len(s)):
    if R > 0 and s[R-1] == 'C' and s[R] == 'D':
        cd += 1
    while cd > 160:
        if L+1 <= R and s[L] == 'C' and s[L+1] == 'D':
            cd -= 1
        L += 1
    if cd == 160:
        best = max(best, R - L + 1)
print(best)

Раздел C. Регулярные выражения и “скользящие окна” как альтернативы

C1. Замена циклов на регулярные выражения

# A6: максимальный блок из A/B/C через re
import re
s = open('k7.txt').read()
print(max((len(m) for m in re.findall(r'[ABC]+', s)), default=0))

C2. Окна для «без подстроки BAD»

# A10 через окно (эффективно, без .find на каждом шаге)
s = open('24_10.txt').read()
bad = 'XZZY'
L = best = 0
cnt = 0  # длина текущего окна
for R, ch in enumerate(s):
    cnt += 1
    # если плохой шаблон кончается в R, двигаем L за его начало
    if R >= 3 and s[R-3:R+1] == bad:
        L = R - 3 + 1
        cnt = R - L + 1
    if cnt > best: best = cnt
print(best)

Раздел D. Короткий чек-лист

  • Всегда сначала уточняем алфавит и строгие ограничения (ведущие нули, соседние знаки, формат чисел).
  • Максимальные/минимальные длины подстрок — чаще всего один проход с локальным счётчиком.
  • Когда условие зависит от «количества чего-то в окне» — используем скользящее окно с подсчётами.
  • Сложные форматы удобно сначала вытащить через регулярки, затем “дочистить” логикой.

Задания для подготовки

Вводные задания

Исходные данные.

a= ['Y', 'Z', 'X', 'Y', 'X', 'X', 'Y', 'Y', 'Z', 'X', 'X', 'X', 'X', 'Z', 'X', 'Z', 'Y', 'X', 'X', 'Z', 'X', 'X', 'X', 'Z', 'Y', 'X', 'Y', 'X', 'Z', 'Y', 'X', 'Z', 'X', 'X', 'Z', 'Z', 'Y', 'Z', 'X', 'Y', 'Z', 'Y', 'Z', 'Z', 'Z', 'Y', 'X', 'Y', 'X', 'Y', 'Z', 'X', 'X', 'Y', 'Y', 'Z', 'Z', 'Z', 'Y', 'X', 'X', 'Y', 'Z', 'X', 'Z', 'Z', 'X', 'Y', 'Y', 'Y', 'X', 'Y', 'X', 'Z', 'X', 'Y', 'Z', 'Y', 'X', 'Y', 'Y', 'Y', 'Z', 'Z', 'Z', 'X', 'X', 'X', 'Y', 'Y', 'X', 'X', 'Z', 'Y', 'Y', 'X', 'Z', 'Z', 'Y', 'X', 'Z', 'X', 'Y', 'Z', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Z', 'X', 'X', 'Z', 'Z', 'Y', 'X', 'X', 'X', 'Z', 'Y', 'Y', 'Z', 'Z', 'Y', 'Y', 'Z', 'X', 'Y', 'X', 'Z', 'Z', 'Z', 'X', 'Z', 'Y', 'Y', 'Z', 'Y', 'X', 'X', 'Y', 'Y', 'X', 'Z', 'Y', 'Y', 'X', 'Z', 'Y', 'X', 'Z', 'Z', 'X', 'X', 'Z', 'Z', 'X', 'X', 'X', 'Z', 'Y', 'Z', 'Y', 'Y', 'X', 'Z', 'Z', 'Z', 'X', 'X', 'Y', 'X', 'Z', 'Y', 'X', 'Y', 'Z', 'Z', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Z', 'Y', 'X', 'Z', 'Z', 'Y', 'X', 'X', 'Z', 'Z', 'Y', 'Y', 'Y', 'X', 'X', 'Z', 'Y', 'Z', 'Z', 'Z', 'Z', 'X', 'X', 'Y', 'Z', 'Z', 'X', 'Z', 'Y', 'Y', 'X', 'X', 'Z', 'Y', 'Y', 'Z', 'Y', 'Y', 'Y', 'Z', 'Y', 'Z', 'X', 'Y', 'Y', 'X', 'Y', 'Z', 'X', 'Y', 'X', 'Y', 'Y', 'Y', 'Y', 'Z', 'X', 'Y', 'Z', 'Z', 'Y', 'X', 'X', 'Z', 'Y', 'Z', 'X', 'Z', 'X', 'X', 'Y', 'X', 'Y', 'Y', 'X', 'X', 'Y', 'Y', 'Z', 'Z', 'Z', 'Y', 'Y', 'Z', 'X', 'X', 'Y', 'Y', 'Y', 'Z', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z', 'Z', 'Y', 'Z', 'Y', 'Y', 'Z', 'Y', 'X', 'X', 'Y', 'Y', 'Z', 'Z', 'Z', 'X', 'X', 'X']

b= ['X', 'A', 'U', 'D', 'I', 'B', 'R', 'O', 'V', 'W', 'G', 'N', 'N', 'R', 'S', 'G', 'A', 'O', 'X', 'O', 'R', 'E', 'S', 'J', 'O', 'Q', 'K', 'W', 'S', 'I', 'S', 'J', 'O', 'M', 'K', 'B', 'W', 'E', 'U', 'A', 'A', 'S', 'X', 'P', 'O', 'C', 'C', 'I', 'O', 'Q', 'J', 'L', 'G', 'Q', 'M', 'E', 'X', 'N', 'U', 'B', 'N', 'I', 'T', 'N', 'L', 'R', 'D', 'S', 'G', 'C', 'V', 'M', 'P', 'V', 'N', 'N', 'H', 'X', 'W', 'T', 'V', 'R', 'E', 'E', 'G', 'D', 'V', 'B', 'W', 'G', 'W', 'E', 'I', 'H', 'V', 'B', 'T', 'B', 'J', 'L', 'Y', 'D', 'D', 'K', 'Z', 'A', 'E', 'H', 'O', 'R', 'P', 'U', 'U', 'K', 'U', 'Y', 'L', 'W', 'B', 'B', 'X', 'H', 'G', 'X', 'X', 'N', 'M', 'C', 'I', 'L', 'N', 'J', 'T', 'K', 'W', 'H', 'J', 'Z', 'B', 'A', 'Y', 'P', 'F', 'F', 'C', 'M', 'M', 'T', 'R', 'Z', 'J', 'V', 'E', 'J', 'C', 'V', 'O', 'Z', 'N', 'B', 'U', 'R', 'I', 'A', 'J', 'H', 'X', 'I', 'R', 'H', 'K', 'M', 'H', 'H', 'M', 'T', 'Q', 'N', 'W', 'M', 'W', 'T', 'I', 'S', 'P', 'V', 'A', 'K', 'J', 'O', 'Z', 'Y', 'O', 'S', 'N', 'Q', 'K', 'Y', 'T', 'X', 'D', 'O', 'M', 'F', 'M', 'B', 'C', 'F', 'W', 'T', 'V', 'I', 'H', 'Z', 'T', 'L', 'I', 'W', 'K', 'Z', 'J', 'T', 'D', 'F', 'Z', 'I', 'O', 'J', 'K', 'N', 'U', 'F', 'R', 'Q', 'W', 'P', 'M', 'S', 'N', 'D', 'H', 'M', 'S', 'R', 'Z', 'F', 'P', 'J', 'U', 'K', 'C', 'D', 'F', 'O', 'E', 'P', 'J', 'K', 'U', 'Z', 'X', 'U', 'S', 'F', 'T', 'W', 'M', 'V', 'M', 'K', 'O', 'F', 'S', 'G', 'T', 'V', 'F', 'E', 'Y', 'W', 'C', 'D', 'D', 'Z', 'M', 'A', 'O', 'K', 'A', 'S', 'A', 'O', 'Y', 'N', 'S', 'K', 'U', 'P', 'U', 'S', 'I', 'B', 'X', 'K', 'X', 'L', 'L', 'C', 'L', 'L', 'Y', 'Y', 'E', 'K', 'D', 'M', 'U', 'D', 'T', 'S', 'Q', 'R', 'U', 'D', 'K', 'S', 'K', 'W', 'N', 'K', 'G', 'R', 'I', 'P', 'D', 'E', 'I', 'I', 'P', 'W', 'G', 'O', 'H', 'P', 'O', 'V', 'S', 'B', 'I', 'D', 'O', 'V', 'F', 'H', 'E', 'B', 'O', 'L', 'C', 'Z', 'I', 'I', 'N', 'Q', 'O', 'Q', 'R', 'J', 'L', 'D', 'E', 'K', 'N', 'O', 'G', 'U', 'X', 'T', 'E', 'E', 'P', 'L', 'H', 'N', 'M', 'N', 'K', 'D', 'K', 'H', 'T', 'X', 'M', 'J', 'J', 'U', 'S', 'X', 'T', 'Y', 'O', 'Z', 'V', 'E', 'O', 'E', 'I', 'Q', 'K', 'J', 'J', 'L', 'Q', 'V', 'M', 'X', 'J', 'Q', 'M', 'X', 'I', 'O', 'T', 'M', 'X', 'Q', 'Y', 'A', 'H', 'S', 'E', 'T', 'D', 'F', 'O', 'V', 'E', 'I', 'N', 'F', 'C', 'U', 'E', 'M', 'D', 'J', 'I', 'X', 'I', 'S', 'A', 'G', 'Z', 'W', 'H', 'A', 'A', 'V', 'L', 'T', 'X', 'N', 'R', 'I', 'H', 'B', 'U', 'E', 'R', 'O', 'F', 'M', 'L', 'U', 'N', 'D', 'P', 'N', 'C', 'C', 'J', 'B', 'P', 'D', 'R', 'K', 'W', 'K', 'S', 'L', 'I', 'Q', 'D', 'O', 'M', 'Z', 'P', 'K', 'A', 'R']

Задания

  1. В списке a, найдите максимальное число подряд идущих букв Z
  2. В списке a, найдите максимальное число подряд идущих букв (произвольных). Если таких цепочек несколько, вывести каждую цепочку и ее длину. Смотреть разбор
  3. В списке a, найдите максимальное число подряд идущих символов, среди которых каждые два соседних различны. Смотреть разбор
  4. В списке a, найдите количество цепочек длины 3, удовлетворяющих следующим условиям:
    1. 1-й символ – один из символов Z или X;
    2. 2-й символ – один из символов X или Y который не совпадает с первым;
    3. 3-й символ – один из символов Y или Z, который не совпадает со вторым
  5. В списке а, найдите максимальную длину цепочки из символов X,Y в произвольном порядке.
  6. В списке а, найдите максимальную длину цепочки вида XYZXYZXYZ…(составленной из фрагментов XYZ, последний фрагмент может быть неполным)
  7. В списке b, определите символ, который чаще всего встречается в файле сразу после буквы E.

Например, в тексте EBCEEBEDDD после буквы E два раза стоит B, по одному разу — E и D. Для этого текста ответом будет B

  1. В списке b, определите максимальное расстояние между двумя произвольными одинаковыми символами.
  2. В списке a, определите максимальное количество идущих подряд символов, среди которых нет подстроки XZZY

Простые

https://kompege.ru/task?id=21

https://kompege.ru/task?id=66

https://kompege.ru/task?id=279

https://kompege.ru/task?id=857

https://kompege.ru/task?id=860

Средние

https://inf-ege.sdamgia.ru/problem?id=35998  Смотреть разбор

https://inf-ege.sdamgia.ru/problem?id=27689  Смотреть разбор

https://kompege.ru/task?id=21421  Смотреть разбор

https://education.yandex.ru/ege/collections/a97d888a-5402-4044-bb08-35bcc66f9ec7/task/24  Смотреть разбор

Сложные

https://inf-ege.sdamgia.ru/problem?id=59847 Разбор алгоритма скользящих окон Смотреть разбор

Понравилась статья? Поделиться с друзьями:
Школа Виктора Комлева