ФИПИ · ЕГЭ · все форматы ответа · 2475 заданий
Тип задачи: Обработка текстового файла.
| КЭС: | 3.9 Обработка символьных данных. Встроенные функции языка программирования для обработки символьных строк. Алгоритмы обработки символьных строк: подсчёт количества появлений символа в строке, разбиение строки на слова по пробельным символам, поиск подстроки внутри данной строки, замена найденной подстроки на другую строку. Генерация всех слов в некотором алфавите, удовлетворяющих заданным ограничениям. Преобразование числа в символьную строку и обратно |
| Тип ответа: | Краткий ответ |
Ответ: 780
Решение.
В приложенном файле 7776782 символов данных. Рассматриваем непрерывные фрагменты строки; символы нельзя переставлять или пропускать. Сохраним приложенный текстовый файл под именем data.txt. Конечный перевод строки удаляем, остальные символы сохраняем.
Требуется минимальная длина при ровно 90 буквах W и не менее 110 сочетаниях 2025. Используем два указателя: left и right ограничивают текущее окно. Счётчики wc и pc хранят соответственно число букв и целых сочетаний внутри окна.
При добавлении очередного символа обновляем wc. Новое сочетание 2025 может закончиться только в right, поэтому проверяем последние 4 символа. Если букв стало больше 90, сдвигаем left вправо, удаляя вклад уходящих символов и сочетаний.
Пока букв ровно 90, а сочетаний не менее 110, окно подходит. Запоминаем его длину и пробуем сократить слева. Когда условие перестаёт выполняться, переходим к следующему правому концу. Удаление слева не может увеличить ни один счётчик; ранее отброшенное начало уже давало подходящее окно меньшей либо равной длины. Поэтому оптимум не теряется.
При уходе левого символа уменьшаем pc только тогда, когда именно в нём начиналось целое сочетание 2025 внутри окна. Это сохраняет правильный учёт на обеих границах. Каждый указатель движется только вперёд, время работы пропорционально длине строки.
Программа:
import re
with open("data.txt", encoding="utf-8-sig") as f:
s = f.read().rstrip("\r\n")
left = wc = pc = 0
answer = len(s) + 1
for right, c in enumerate(s):
wc += c == 'W'
if right - 3 >= left:
pc += s[right - 3:right + 1] == '2025'
while wc > 90:
wc -= s[left] == 'W'
if left + 3 <= right:
pc -= s.startswith('2025', left)
left += 1
while wc == 90 and pc >= 110:
answer = min(answer, right - left + 1)
wc -= s[left] == 'W'
if left + 3 <= right:
pc -= s.startswith('2025', left)
left += 1
print(answer)Проверка результата. Нумеруем символы исходной строки с единицы. Один из оптимальных фрагментов имеет следующие границы:
| Характеристика | Значение |
|---|---|
| Первый символ | 7616926 |
| Последний символ включительно | 7617705 |
| Длина в символах | 780 |
Разность границ с учётом обоих концов: 7617705 − 7616926 + 1 = 780.
В найденном фрагменте ровно 90 букв W и 110 сочетаний 2025. Оба требования выполнены. Независимый перебор возможных начальных событий с двоичным поиском концов подтвердил тот же минимум.
Полный проход по приложенному файлу даёт итоговый ответ. Проверка коротких строк полным перебором всех подстрок подтверждает обработку крайних случаев.
Ответ: 780.
Напишите пожелание к сайту или решению либо сообщите о найденной неточности в задании EGEINF5605A0.
Сообщение увидит только команда сайта: на странице оно не публикуется.
Комментарии к решению
Комментарии видны всем посетителям сайта.
Комментариев пока нет. Будьте первым.
Чтобы оставить комментарий, войдите или зарегистрируйтесь.