Теория
Открытие и чтение текстовых файлов
# Вариант 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
- Строковые методы:
count,find/rfind,replace, срезы,split/join. - Работа с файлами:
open, чтение целиком/построчно, контекстный менеджерwith. - Итерации и индексы:
range, проход по символам, склейка результатов, аккуратная инициализация максимумов. - Регулярные выражения в 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']
Задания
- В списке a, найдите максимальное число подряд идущих букв
Z - В списке a, найдите максимальное число подряд идущих букв (произвольных). Если таких цепочек несколько, вывести каждую цепочку и ее длину. Смотреть разбор
- В списке a, найдите максимальное число подряд идущих символов, среди которых каждые два соседних различны. Смотреть разбор
- В списке a, найдите количество цепочек длины 3, удовлетворяющих следующим условиям:
- 1-й символ – один из символов
ZилиX; - 2-й символ – один из символов
XилиYкоторый не совпадает с первым; - 3-й символ – один из символов
YилиZ, который не совпадает со вторым
- 1-й символ – один из символов
- В списке а, найдите максимальную длину цепочки из символов
X,Yв произвольном порядке. - В списке а, найдите максимальную длину цепочки вида
XYZXYZXYZ…(составленной из фрагментовXYZ, последний фрагмент может быть неполным) - В списке b, определите символ, который чаще всего встречается в файле сразу после буквы
E.
Например, в тексте EBCEEBEDDD после буквы E два раза стоит B, по одному разу — E и D. Для этого текста ответом будет B
- В списке b, определите максимальное расстояние между двумя произвольными одинаковыми символами.
- В списке a, определите максимальное количество идущих подряд символов, среди которых нет подстроки
XZZY
Простые
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 Разбор алгоритма скользящих окон Смотреть разбор
