ФИПИ · ЕГЭ · все форматы ответа · 2475 заданий
Тип задачи: Обработка текстового файла.
| КЭС: | 3.9 Обработка символьных данных. Встроенные функции языка программирования для обработки символьных строк. Алгоритмы обработки символьных строк: подсчёт количества появлений символа в строке, разбиение строки на слова по пробельным символам, поиск подстроки внутри данной строки, замена найденной подстроки на другую строку. Генерация всех слов в некотором алфавите, удовлетворяющих заданным ограничениям. Преобразование числа в символьную строку и обратно |
| Тип ответа: | Краткий ответ |
Ответ: 2287
Решение.
Считываем исходный текстовый файл одной строкой и убираем завершающий перевод строки. Получаем 10000000 символов. Порядок символов менять нельзя: требуется непрерывный фрагмент исходного текста.
Нужно найти самый длинный фрагмент, содержащий ровно 190 вхождений пары BC. Пара учитывается только целиком: буква B должна стоять внутри фрагмента непосредственно перед C. Одиночная B на правой границе или C на левой границе не образует вхождения.
Используем окно от left до right включительно. Продвигаем правую границу по одному символу. Если добавленная C непосредственно следует за B, число вхождений count увеличивается на один.
Пока count больше 190, сдвигаем left вправо. Если удаляемый левый символ — B, а следующий — C, одно вхождение исчезает, поэтому уменьшаем count. При удалении любого другого символа count не меняется.
После этого окно содержит не более 190 вхождений. Если их ровно 190, его длина равна right − left + 1, и ею обновляем максимум. Окна с меньшим числом вхождений в ответ не включаем.
Для каждого right граница left является самой ранней допустимой после удаления лишних пар. Сдвигать её дальше невыгодно: окно станет короче. Начать левее нельзя: там было бы больше 190 вхождений. Поэтому максимум по всем right даёт искомую длину.
Сохраните скачанный файл рядом с программой под исходным именем. Программа на Python:
with open("img1_1777467523.txt") as f:
s = f.read().strip()
k = 190
left = count = best = 0
for right in range(len(s)):
if right > 0 and s[right - 1] == 'B' and s[right] == 'C':
count += 1
while count > k:
if s[left] == 'B' and s[left + 1] == 'C':
count -= 1
left += 1
if count == k:
best = max(best, right - left + 1)
print(best)Для исходного файла получаем best = 2287.
Проверка: достигающий фрагмент находится на позициях 8423822–8426108 при нумерации от единицы. Его длина 8426108 − 8423822 + 1 = 2287; в нём ровно 190 пар BC.
При нумерации от нуля первая включённая пара начинается на позиции 8423837, последняя — на 8426082. Предыдущая пара начинается на 8423820, следующая — на 8426107. Поэтому фрагмент начинается с C предыдущей пары и заканчивается B следующей: эти две внешние пары целиком в окно не входят.
Независимая проверка перечислила все 1055932 позиций BC. Для каждого блока из 190 последовательных вхождений вычислены максимально возможные внешние границы с учётом начала и конца файла; наибольшая длина снова равна 2287.
Обе границы движутся только вправо, поэтому суммарно сдвигаются не более n раз каждая. Время O(n), дополнительная память для счётчиков O(1), хранение исходной строки O(n).
Ответ: 2287.
Напишите пожелание к сайту или решению либо сообщите о найденной неточности в задании EGEINF88B226.
Сообщение увидит только команда сайта: на странице оно не публикуется.
Комментарии к решению
Комментарии видны всем посетителям сайта.
Комментариев пока нет. Будьте первым.
Чтобы оставить комментарий, войдите или зарегистрируйтесь.