Как решать задание 26 ЕГЭ по информатике — сортировка и обработка данных
Разбор задания 26 ЕГЭ по информатике 2026: жадные алгоритмы, сортировка по нескольким ключам, работа с файлами А и Б. Полный шаблон решения на Python с примерами.
Задание 26 — одно из двух «тяжёлых» заданий в конце КЕГЭ (вместе с заданием 27). Оно стоит 2 первичных балла — столько же, сколько задание 27, но отдельный сюжет: здесь не кластерный анализ, а сортировка, жадные алгоритмы и обработка больших объёмов данных. И если задание 27 многим кажется страшным из-за слова «кластеризация», то задание 26 на первый взгляд простое — но именно на нём теряют баллы те, кто не разобрался с деталями.
Разберём всё по порядку: что в задании 26, какие бывают формулировки, как выбирать критерий жадности, полный шаблон кода и типичные ошибки.
О задании 26 коротко
| Параметр | Значение |
|---|---|
| Номер | 26 из 27 |
| Баллов | 2 (по 1 за каждый из двух файлов) |
| Время | 30-40 минут рекомендуется |
| Файл А | до 1000 записей |
| Файл Б | до 10 000-100 000 записей |
| Тип | обработка массива данных |
| Ключевой навык | сортировка + жадный алгоритм |
На экзамене тебе дают два текстовых файла — файл А (простой) и файл Б (сложный). В каждом — последовательность записей. Типовая запись — это либо пара (индекс, значение), либо строка с несколькими полями (например, ID, время, приоритет). Нужно для каждого файла отдельно вычислить ответ по формуле из условия и записать два числа (или две пары чисел).
Логика задания для файлов А и Б одинаковая — меняется только размер входных данных. Это значит: если ты отладил решение на файле А и оно работает за O(n log n) — оно отработает и на файле Б. Если на файле А написал квадратный алгоритм (перебор всех пар) — на файле Б он либо не досчитает, либо будет считать до конца экзамена.
Типовые формулировки
Разберём 4 типа задач, которые в 95% случаев встречаются в задании 26. За ними стоит одна и та же идея: отсортируй по правильному ключу, пройди жадно, собери ответ.
Тип 1. «Успеть максимум дел»
Дано N задач, у каждой — длительность
tи ценностьv. У тебя есть общий бюджет времени T. Какой набор задач нужно взять, чтобы суммарная ценность была максимальной?
Это классическая задача о рюкзаке в «дробной» формулировке. Если задачи можно брать только целиком — жадный алгоритм по убыванию плотности v/t даёт оптимум в 90% случаев, которые встречаются в ЕГЭ (составители обычно подбирают данные так, что жадность работает).
Критерий сортировки: по убыванию v/t (ценность на единицу времени).
Тип 2. «Расписание без пересечений»
Даны N интервалов
(начало, конец). Нужно выбрать максимальное количество непересекающихся.
Классика, разбирается в первой главе любой книги по жадным алгоритмам. Критерий — сортировка по концу. Идём по отсортированному списку, берём первый интервал, потом каждый следующий, у которого начало ≥ конца последнего взятого.
Критерий сортировки: по возрастанию времени конца.
Тип 3. «K-й по порядку»
Найди N-й элемент, если отсортировать записи по такому-то критерию.
Тут даже жадность не нужна — просто правильная сортировка и выборка элемента по индексу. Коварство в том, что критерий обычно составной: например, «сортировать по убыванию суммы полей 2 и 3, при равной сумме — по возрастанию ID».
Критерий сортировки: составной, читай условие как инструкцию.
Тип 4. «Грузоподъёмность / рюкзак»
Есть N предметов с весом
wи ценностьюv. Грузовик везёт W кг. Максимальная суммарная ценность?
Это дискретный рюкзак. В общем случае он решается через динамическое программирование за O(n·W). Но в ЕГЭ-версии W обычно большое (10^6), зато составители подбирают веса так, что жадность по плотности даёт правильный ответ — либо задача формулируется так, что любой предмет можно взять частично.
Критерий сортировки: по убыванию v/w.
Главный приём — сортировка по нескольким ключам
В Python это делается одной строкой. Ключ передаётся в функцию sorted() через key=, и если ключей несколько — возвращаешь кортеж:
# Сортировка по убыванию ценности, при равной ценности — по возрастанию ID
data.sort(key=lambda x: (-x['value'], x['id']))
# Сортировка по убыванию плотности, при равной — по номеру
data.sort(key=lambda x: (-x['value'] / x['time'], x['id']))
# Сортировка по времени конца (классика задач на расписания)
intervals.sort(key=lambda x: x['end'])
Знак минус в -x['value'] инвертирует сортировку для этого поля — при этом остальные поля сортируются в обычном порядке. Это удобнее, чем писать reverse=True (который инвертирует все поля).
Почему не reverse=True
# ПЛОХО — инвертирует и value, и id
sorted(data, key=lambda x: (x['value'], x['id']), reverse=True)
# ХОРОШО — инвертирует только value, id сортируется по возрастанию
sorted(data, key=lambda x: (-x['value'], x['id']))
На экзамене это критично: при одинаковой ценности типовое условие требует меньший ID, и reverse=True даст неправильный ответ.
Полный шаблон решения на Python
Это универсальный скелет — под любой тип задания 26 в нём меняются только две строки.
# Читаем входной файл
with open('26-A.txt', 'r', encoding='utf-8') as f:
# Первая строка — параметры (N, лимит времени, количество кластеров и т.п.)
N, T = map(int, f.readline().split())
data = []
for i in range(N):
parts = f.readline().split()
# Подстраиваем под формат: обычно (длительность, ценность)
t, v = int(parts[0]), int(parts[1])
data.append({'id': i + 1, 't': t, 'v': v})
# Сортируем по нужному критерию (тут — по убыванию плотности v/t)
data.sort(key=lambda x: (-x['v'] / x['t'], x['id']))
# Жадный проход
total_time = 0
total_value = 0
taken = []
for item in data:
if total_time + item['t'] <= T:
total_time += item['t']
total_value += item['v']
taken.append(item['id'])
print(total_value, len(taken))
Этот код решает задачу «успеть максимум дел за время T». Замени строку сортировки и условие внутри цикла — получишь решение для любого типа из четвёрки выше.
Полный пример. «Выбрать N заданий с максимальной ценностью»
Разберём задачу целиком, чтобы стало понятно, как критерий сортировки влияет на ответ.
Условие
В школе прошёл хакатон. У организаторов есть список из N заданий (до 10 000 — это файл Б). Для каждого задания известны:
- длительность в минутах
t(от 5 до 300), - ценность
v— сколько баллов команда получит за его выполнение (от 10 до 1000).
У команды есть T минут (обычно 480 — 8 часов). Команда не может прерывать задание, раз уж начала. Команда хочет набрать максимальную суммарную ценность.
Найди эту максимальную ценность и количество выбранных заданий.
Формат файла
10000 480
12 150
45 720
8 90
...
Первая строка — N и T, дальше N строк с парами (t, v).
Разбор
Почему сортировка по v/t, а не по v? Возьмём на пальцах три задания и T = 30:
| ID | t | v | v/t |
|---|---|---|---|
| 1 | 20 | 100 | 5.0 |
| 2 | 10 | 60 | 6.0 |
| 3 | 15 | 75 | 5.0 |
Сортировка по убыванию v даст последовательность [1, 3, 2] → берём 1 (10 минут осталось), 3 не влезает (15 > 10), берём 2 → итого 100 + 60 = 160. Успели 2 задания.
Сортировка по убыванию v/t даст [2, 1, 3] → берём 2 (20 минут осталось), берём 1 (осталось 0), 3 не влезает → итого 60 + 100 = 160. То же самое? В этом примере — да, потому что обе жадности уложились в 30 минут.
А теперь T = 25. По v → берём 1 (осталось 5), 3 не влезает, 2 не влезает → 100. По v/t → берём 2 (осталось 15), берём 3 (осталось 0) → 60 + 75 = 135. Вот где критерий v/t обгоняет.
Плотность отражает, сколько ценности приносит минута времени. Если ты берёшь задания в порядке от самого «плотного» — ты максимально эффективно используешь каждую минуту.
Код решения
def solve(filename):
with open(filename, 'r', encoding='utf-8') as f:
first = f.readline().split()
N, T = int(first[0]), int(first[1])
tasks = []
for i in range(N):
t_str, v_str = f.readline().split()
t = int(t_str)
v = int(v_str)
tasks.append((t, v, i + 1))
# Сортируем по убыванию v/t, при равной плотности — по возрастанию ID
tasks.sort(key=lambda x: (-x[1] / x[0], x[2]))
time_left = T
total_value = 0
count = 0
for t, v, task_id in tasks:
if t <= time_left:
time_left -= t
total_value += v
count += 1
return total_value, count
value_a, count_a = solve('26-A.txt')
print('A:', value_a, count_a)
value_b, count_b = solve('26-B.txt')
print('B:', value_b, count_b)
Один и тот же код работает для файла А (N ≤ 1000) и для файла Б (N ≤ 10 000). Сложность — O(N log N), на файле Б отрабатывает за доли секунды.
На что смотреть при проверке ответа
- Сумма совпадает с ценностью — ещё раз проверь, что выводишь, что просит условие (ценность, а не количество или наоборот).
- Осталось меньше минимальной длительности — если у тебя после жадности осталось ещё 20 минут свободных, но все оставшиеся задачи длиннее 20 минут — всё нормально, это предел жадного подхода.
- Файл А и файл Б дают правдоподобные порядки чисел — файл Б должен давать бОльший ответ, потому что записей больше.
Разница А против Б — когда ломается решение
Файл А можно решить несколькими способами, даже если ты не угадал оптимальный критерий сортировки. Ниже — что работает для А и ломается для Б.
Решения, которые работают для А и не работают для Б
| Подход | Файл А (N ≤ 1000) | Файл Б (N ≤ 10000) |
|---|---|---|
| Полный перебор подмножеств | не успеет | не успеет |
| O(N²) двойной цикл | ~0.5 сек — OK | ~50 сек — не успеет |
| O(N log N) сортировка | 0.01 сек | 0.1 сек — OK |
| ДП по таблице N×T | зависит от T | зависит от T |
Вывод: всегда пиши O(N log N) с сортировкой, даже для файла А. Время на экзамене дороже, чем экономия 3 строк кода.
Типовые «ломающие» детали в файле Б
- Большие числа — если ценность до 10^9, не забывай, что Python умеет большие числа нативно, но на C++ получишь переполнение в
int. - Одинаковые значения — в файле Б почти гарантированно встречаются задания с одинаковой плотностью. Без вторичного ключа сортировки получишь «плавающий» ответ, если прогоняешь тот же код несколько раз.
- Флоат-сравнения — если сортируешь по
v/t, из-за ошибок округления жадность может пойти не туда. Лечится умножением на знаменатель: сравнивайv1 * t2сv2 * t1вместоv1/t1сv2/t2.
# Надёжнее, чем v/t — сравниваем без флоатов
from functools import cmp_to_key
def compare(a, b):
# a и b — кортежи (t, v, id)
left = a[1] * b[0] # v_a * t_b
right = b[1] * a[0] # v_b * t_a
if left > right:
return -1
if left < right:
return 1
return a[2] - b[2]
tasks.sort(key=cmp_to_key(compare))
Но в 95% задач ЕГЭ v/t через float работает нормально — числа не настолько близкие, чтобы флоат врал.
Типичные ошибки на задании 26
Ошибка 1. Неверный критерий сортировки
Самая распространённая. Сортируют по ценности, а надо по плотности. Или по длительности (чтобы «успеть больше задач» — но это даёт малое количество дорогих заданий). Лечится тестом на малом примере вручную: возьми 4-5 записей, найди оптимум перебором, сравни с жадностью. Если сходится — критерий верный.
Ошибка 2. Забыл сдать один из двух файлов
На экзамене сдаёшь два ответа — для файла А и файла Б. Оба поля обязательны. Если сдал только А — получишь 1 балл из 2. Если сдал только Б с неверным А — тоже только 1 балл (за Б, если он правильный). Пиши оба ответа сразу после каждого прогона.
Ошибка 3. Путаница int и float
# ПЛОХО: total_value — float, ответ принимается только как int
total_value = 0.0
# ХОРОШО
total_value = 0
Если в условии сказано «вывести целое число» и ты выводишь 123.0 — ответ может не зачесть строгая проверка. Приводи через int() или считай в int с самого начала.
Ошибка 4. Забыл про первую строку файла
В большинстве задач первая строка — это параметры (N, T, W — что угодно). Если ты сразу начнёшь читать её как данные, у тебя съедет вся последующая обработка. Всегда отдельно читай первую строку.
Ошибка 5. Неверная обработка строковых полей
Иногда в файле приходят не числа, а строки-идентификаторы (A0012, BC17). Их нельзя переводить в int — сравнивай как строки или как хеши. Если в условии просят отсортировать по ID как по строке — используй sorted(..., key=lambda x: x['id']) без преобразований.
Сколько времени закладывать на экзамене
КЕГЭ длится 235 минут. Разбивка, которая работает у 90-балльников:
| Блок | Заданий | Время |
|---|---|---|
| 1-10 | 10 | 40-50 мин |
| 11-20 | 10 | 60-80 мин |
| 21-25 | 5 | 40-50 мин |
| 26 | 1 | 30-40 мин |
| 27 | 1 | 40-50 мин |
| Проверка | — | 20-30 мин |
Если на 26 тратишь больше 40 минут — фиксируй ответ по файлу А и переходи к 27. Файл Б ценнее 1 балла, но и 27 даёт 2 балла — промахнуться с таймингом хуже, чем не добрать 1 балл за файл Б.
Если перед экзаменом хочешь выстроить план подготовки целиком — посмотри план на 3 месяца или на 6 месяцев. Там задания 26-27 занимают отдельную неделю каждое.
Как тренироваться
Шаг 1. Освой шаблон
Возьми шаблон из этой статьи (раздел «Полный шаблон решения»). Адаптируй под все 4 типа задач из раздела «Типовые формулировки». Напиши 4 версии — по одной для каждого типа. После этого у тебя в голове будет «словарь критериев сортировки».
Шаг 2. Прорешай по 5 вариантов каждого типа
Где брать варианты:
- ФИПИ — открытый банк (есть задания 26 прошлых лет).
- Поляков-сайт (kpolyakov.spb.ru) — сотни задач с автопроверкой.
- Тренажёр TuteMe — задания с разборами от составителей ЕГЭ и подсказками по критерию сортировки.
На каждом прорешанном варианте фиксируй: какой тип, какой критерий, за сколько минут решил. К 10-му варианту у тебя выработается чутьё на тип задачи уже по формулировке.
Шаг 3. Тренируйся на времени
Поставь таймер на 40 минут. Возьми задание 26 (А + Б) и реши его полностью — включая время на чтение условия, отладку, ввод ответа. В 30-35 минут должен укладываться даже на первом раунде. Если медленнее — вернись к шагу 2.
Шаг 4. Разбор ошибок
После каждого неправильного ответа не смотри решение сразу. Попробуй найти ошибку сам: печатай промежуточные результаты, сравнивай с тестовыми данными из условия (они всегда даются). Если за 15 минут не нашёл — смотри разбор. Но собственный разбор ценнее для памяти.
Шире про навыки подготовки — в разборе демоверсии ЕГЭ 2026 и статье об изменениях в ЕГЭ 2026.
Чек-лист перед тем, как сдавать задание 26
- Прочитал условие дважды и понял, что от тебя требуют вывести (ценность, количество, ID, сумму).
- Определил тип задачи: «успеть дела» / «расписание» / «K-й по порядку» / «рюкзак».
- Выбрал критерий сортировки. Сверил на мини-примере 4-5 элементов.
- Написал код так, чтобы он работал и для А, и для Б без изменений.
- Прогнал на файле А. Сверил с примером из условия (если дан).
- Прогнал на файле Б. Уложился по памяти и времени.
- Сдал оба ответа в нужные поля формы.
Коротко главное
- Задание 26 стоит 2 балла, состоит из двух файлов (А — до 1000 записей, Б — до 10 000+).
- Логика для А и Б одна, разница только в объёме данных.
- В 90% случаев решение = правильная сортировка + жадный проход.
- Критерий сортировки — главная интеллектуальная часть задачи. Всегда проверяй на малом примере.
- Используй Python и
sorted(key=lambda x: ...)с кортежем из нескольких ключей. - Сдавай ответ по файлу А всегда — даже если Б не успел. 1 балл лучше 0.
- Тайминг на экзамене — 30-40 минут суммарно, не больше.
Если пока цепляешься на более ранних задачах — начни с разборов задания 12 (обработка строк) или задания 6 (анализ алгоритмов Робота). Там тоже нужна сортировочная логика, но объёмы поменьше, и цена ошибки ниже. К заданию 26 возвращайся, когда уверенно решаешь всё до 25-го.