Содержание
ЕГЭ по информатике сдают за компьютером, и последние четыре задания — 24, 25, 26 и 27 — обычно решают программой. Язык можно выбрать любой из установленных в пункте проведения экзамена. C++ среди них есть почти всегда: он быстрый, и для заданий с большими файлами это заметное преимущество.
В статье — что известно об экзамене 2027 года и по одной учебной задаче на каждое из четырёх заданий с решением на C++. Задачи составлены нами по образцу экзаменационных, а все программы проверены на сгенерированных данных.
Что известно о ЕГЭ-2027
На момент написания статьи (октябрь 2026 года) ФИПИ опубликовал демоверсию, спецификацию и кодификатор 2027 года в виде проектов: замечания к ним принимались до 30 сентября. Окончательные документы могут отличаться, поэтому сверяйтесь с сайтом ФИПИ.
Что следует из проекта и сообщений Рособрнадзора:
- структура экзамена сохраняется: 27 заданий, 3 часа 55 минут, максимум 29 первичных баллов;
- задания 26 и 27 оцениваются в 2 балла, остальные — в 1;
- тематика трёх заданий изменена — каких именно и как, смотрите в спецификации;
- в задании 27 упрощена запись ответа: одна строка из двух чисел;
- файлы к заданиям 17, 24, 26 и 27 — текстовые, в формате
.txt.
Общая заготовка: чтение файла
В заданиях 24, 26 и 27 данные лежат в файле. Положите его в папку с программой и читайте через std::ifstream — точно так же, как через std::cin:
#include <fstream>
#include <iostream>
int main() {
std::ifstream file("24.txt");
if (!file) {
std::cout << "Файл не открылся\n";
return 1;
}
// дальше: file >> значение;
}
Проверка if (!file) экономит минуты: если файл назван иначе или лежит в другой папке, программа скажет об этом сразу, а не выведет ноль.
Задание 24. Обработка строки
Тип. В файле — одна длинная строка. Нужно найти самую длинную цепочку символов с заданным свойством.
Учебная задача. Файл 24.txt содержит строку из букв A, B и C длиной до миллиона символов. Найдите длину самой длинной цепочки, в которой никакие две соседние буквы не совпадают.
Идея. Идём по строке один раз и держим длину текущей подходящей цепочки. Если буква совпала с предыдущей, цепочка обрывается и начинается заново с этой буквы.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream file("24.txt");
std::string s;
file >> s;
int best = 0;
int current = 0;
for (std::size_t i = 0; i < s.size(); ++i) {
if (i > 0 && s[i] == s[i - 1]) {
current = 1; // цепочка оборвалась: начинаем новую с текущей буквы
} else {
++current;
}
best = std::max(best, current);
}
std::cout << best << '\n';
return 0;
}
Где ошибаются.
- Сбрасывают счётчик в 0, а не в 1: буква, на которой цепочка оборвалась, сама начинает новую.
- Обновляют ответ только при обрыве цепочки и теряют ту, что дошла до конца строки.
- Пишут два вложенных цикла «для каждого начала ищем конец». Для строки в миллион символов это не успеет: нужен один проход.
Задание 25. Делители и маски
Тип. Перебор чисел с проверкой свойства: количество делителей, простота, соответствие маске. Файла нет, программа сама перебирает числа.
Учебная задача. Среди чисел от 800 000 до 800 100 найдите те, у которых ровно четыре различных натуральных делителя. Для каждого выведите само число и его наибольший делитель, не равный самому числу.
Идея. Делители идут парами: если d делит n, то и n / d делит n. Поэтому достаточно перебирать d до корня из n.
#include <iostream>
#include <vector>
int main() {
for (long long n = 800000; n <= 800100; ++n) {
std::vector<long long> divisors;
for (long long d = 1; d * d <= n; ++d) {
if (n % d == 0) {
divisors.push_back(d);
if (d != n / d) divisors.push_back(n / d);
}
if (divisors.size() > 4) break; // делителей уже слишком много
}
if (divisors.size() == 4) {
long long largest = 0;
for (long long d : divisors) {
if (d != n && d > largest) largest = d;
}
std::cout << n << ' ' << largest << '\n';
}
}
return 0;
}
Программа выводит 21 строку, первые три: 800003 47059, 800005 160001, 800013 266671.
Маски. В другом варианте задания числа должны подходить под маску, где ? — одна любая цифра, а * — любая последовательность цифр, в том числе пустая. Например: найти числа, не превышающие 10^9, которые подходят под маску 12*4?5 и делятся на 2027.
Здесь важны две вещи. Первая: перебирать нужно не все числа, а только кратные 2027, с шагом 2027 — это в две тысячи раз быстрее. Вторая: проверку маски удобно написать отдельной функцией.
#include <iostream>
#include <string>
// Подходит ли число (в виде строки) под маску: ? — одна любая цифра, * — любая последовательность цифр.
bool matches(const std::string& mask, const std::string& number, std::size_t i = 0, std::size_t j = 0) {
if (i == mask.size()) return j == number.size();
if (mask[i] == '*') {
for (std::size_t k = j; k <= number.size(); ++k) {
if (matches(mask, number, i + 1, k)) return true;
}
return false;
}
if (j == number.size()) return false;
if (mask[i] == '?' || mask[i] == number[j]) return matches(mask, number, i + 1, j + 1);
return false;
}
int main() {
const std::string mask = "12*4?5";
for (long long n = 2027; n <= 1000000000; n += 2027) { // только числа, кратные 2027
if (matches(mask, std::to_string(n))) {
std::cout << n << ' ' << n / 2027 << '\n';
}
}
return 0;
}
Первые строки вывода: 12192405 6015, 12273485 6055, 12496455 6165.
Где ошибаются.
- Перебирают делители до
n, а не до корня: для чисел порядка 10^9 это не успеет. - Забывают, что у точного квадрата парные делители совпадают, и считают один делитель дважды.
- Используют
intтам, где произведение или само число выходит за два миллиарда.
Задание 26. Сортировка
Тип. В файле — набор чисел или записей. Решение почти всегда начинается с сортировки, после которой ответ находится одним проходом.
Учебная задача. В первой строке файла 26.txt записаны объём диска S и количество файлов N, далее — N чисел, размеры файлов. Нужно сохранить на диск как можно больше файлов. Выведите наибольшее количество файлов и наибольший возможный размер самого большого файла среди всех способов сохранить столько файлов.
Идея. Чтобы файлов было больше, берём самые маленькие. Потом пробуем улучшить второй ответ: последний взятый файл заменяем на более крупный, пока он помещается в освободившееся место.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
int main() {
std::ifstream file("26.txt");
long long capacity;
int n;
file >> capacity >> n;
std::vector<long long> sizes(n);
for (long long& size : sizes) file >> size;
std::sort(sizes.begin(), sizes.end());
// Берём самые маленькие файлы, пока они помещаются.
long long used = 0;
int count = 0;
while (count < n && used + sizes[count] <= capacity) {
used += sizes[count];
++count;
}
// Пробуем заменить последний взятый файл на самый большой из подходящих.
long long largest = count > 0 ? sizes[count - 1] : 0;
if (count > 0) {
long long room = capacity - used + sizes[count - 1];
for (int i = count; i < n && sizes[i] <= room; ++i) {
largest = sizes[i];
}
}
std::cout << count << ' ' << largest << '\n';
return 0;
}
Где ошибаются.
- Отвечают на первый вопрос и забывают про второй: ответ состоит из двух чисел, и для полного балла верными должны быть оба.
- Считают суммы в
int: при больших размерах и тысячах файлов сумма переполняется. - Проверяют решение только на примере из условия. Сделайте файл из пяти-шести чисел, для которого ответ можно посчитать вручную.
Задание 27. Кластеры
Тип. В файле — координаты точек на плоскости. Точки образуют несколько групп — кластеров. Для каждого кластера нужно найти центр — точку кластера, сумма расстояний от которой до остальных его точек наименьшая, — и по центрам вычислить два числа.
Учебная задача. В файле 27.txt в каждой строке записаны координаты точки: x и y. Точки образуют три кластера; расстояние между точками разных кластеров больше 1, а внутри кластера от любой точки можно дойти до любой другой шагами короче 1. Найдите центры кластеров. Выведите два числа: целую часть среднего арифметического абсцисс центров, умноженного на 10 000, и то же для ординат.
Идея. Решение состоит из трёх шагов.
- Прочитать точки. В файле дробная часть может быть отделена запятой — заменяем её на точку.
- Разбить точки на кластеры: от неразмеченной точки «заражаем» всех, кто ближе порога, потом их соседей и так далее.
- В каждом кластере перебрать все точки и для каждой посчитать сумму расстояний до остальных.
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
struct Point {
double x, y;
};
double distance(const Point& a, const Point& b) {
return std::hypot(a.x - b.x, a.y - b.y);
}
int main() {
std::ifstream file("27.txt");
std::vector<Point> points;
std::string sx, sy;
while (file >> sx >> sy) {
std::replace(sx.begin(), sx.end(), ',', '.'); // в файле может стоять десятичная запятая
std::replace(sy.begin(), sy.end(), ',', '.');
points.push_back({std::stod(sx), std::stod(sy)});
}
const double gap = 1.0; // точки одного кластера ближе друг к другу, чем gap
const int n = points.size();
std::vector<int> cluster(n, -1);
int clusters = 0;
// Разбиение на кластеры: обход «соседей» от каждой ещё не размеченной точки.
for (int start = 0; start < n; ++start) {
if (cluster[start] != -1) continue;
std::vector<int> queue = {start};
cluster[start] = clusters;
for (std::size_t head = 0; head < queue.size(); ++head) {
int current = queue[head];
for (int other = 0; other < n; ++other) {
if (cluster[other] == -1 && distance(points[current], points[other]) < gap) {
cluster[other] = clusters;
queue.push_back(other);
}
}
}
++clusters;
}
// Центр кластера — точка с наименьшей суммой расстояний до остальных его точек.
double sum_x = 0, sum_y = 0;
for (int c = 0; c < clusters; ++c) {
int center = -1;
double best = 0;
for (int i = 0; i < n; ++i) {
if (cluster[i] != c) continue;
double total = 0;
for (int j = 0; j < n; ++j) {
if (cluster[j] == c) total += distance(points[i], points[j]);
}
if (center == -1 || total < best) {
best = total;
center = i;
}
}
sum_x += points[center].x;
sum_y += points[center].y;
}
long long px = static_cast<long long>(std::fabs(sum_x / clusters) * 10000);
long long py = static_cast<long long>(std::fabs(sum_y / clusters) * 10000);
std::cout << px << ' ' << py << '\n';
return 0;
}
Оба вложенных перебора делают порядка N^2 действий. Для десяти тысяч точек это сто миллионов вычислений расстояния — программа на C++ справляется за секунды, и ускорять её не нужно.
Где ошибаются.
- Не замечают десятичную запятую:
file >> xдля вещественного числа читает2,5как 2 и ломает всё дальнейшее чтение. - Подбирают порог
gapнаугад. Сначала посмотрите на точки — откройте файл в электронной таблице и постройте диаграмму: по ней видно и число кластеров, и расстояние между ними. - Выводят число кластеров, не проверив его. Добавьте отладочную строку
std::cout << clusters: если получилось не столько, сколько в условии, порог выбран неверно. - Округляют вместо того, чтобы взять целую часть.
Как распределить время
На экзамен отводится 235 минут. Задания 24–27 требуют написать и отладить программу, поэтому оставляйте на них не меньше полутора часов. Разумный порядок: 24 и 25 — они короче; затем 26; затем 27.
Несколько правил, которые экономят баллы.
- Проверяйте на маленьком примере. Сделайте файл из пяти строк, ответ для которого посчитан вручную.
- Берите
long longдля сумм и произведений. - Не оптимизируйте заранее. Простое решение за N^2 для десяти тысяч чисел проходит; сложное решение с ошибкой — нет.
- Сохраняйте программу перед каждым запуском и ответ — сразу, как получили.
С чего начать подготовку
Задания 24–27 проверяют не знание C++, а умение быстро и без ошибок писать простые программы: циклы, массивы, строки, сортировку. Если эти темы пока даются с трудом, начните с них:
- учебник «Современный C++» — уроки с задачами и автоматической проверкой;
- подборка «Задачи по C++ для начинающих с решениями»;
- статья «Time Limit Exceeded: почему решение не проходит по времени» — как оценить, успеет ли программа;
- статья «Мусор в переменных и неопределённое поведение в C++» — почему ответ иногда «плавает».
Источники
- Демоверсии, спецификации, кодификаторы ЕГЭ — ФИПИ [Электронный ресурс]. — URL: https://fipi.ru/ege/demoversii-specifikacii-kodifikatory (дата обращения: 10.10.2026).
- Рособрнадзор сообщил об изменениях в ОГЭ и ЕГЭ в 2027 году — Эксперт [Электронный ресурс]. — URL: https://expert.ru/news/rosobrnadzor-soobschil-ob-izmeneniyakh-v-oge-i-ege-v-2027-godu (дата обращения: 10.10.2026).
- std::basic_ifstream — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/io/basic_ifstream (дата обращения: 10.10.2026).
- std::sort — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/algorithm/sort (дата обращения: 10.10.2026).


