Разбор задач · олимпиада по информатике Алгоритмы · 8–11 классы

Разбор · информатика · олимпиады

Разбор задач олимпиады по информатике: алгоритмы

Характерные алгоритмические задачи и как уложиться в ограничения

Олимпиада по информатике — это не «написать программу», а придумать эффективный алгоритм и доказать, что он укладывается в ограничения по времени. Ниже — три характерные задачи: поиск пары с заданной суммой, число способов подняться по лестнице и быстрые суммы на отрезках. Для каждой разобраны идея, сложность и краевые случаи.

Классы
8–11
Языки
чаще C++ или Python
Что проверяет
автоматическая проверка по тестам
Что тренируем
алгоритмы и оценка сложности

Коротко о формате

Задача задаёт ограничения на размер входа и время работы. Наивное решение обычно проходит лишь часть тестов — нужно придумать алгоритм с подходящей асимптотикой. Ответ проверяет система по тестам, поэтому важны и идея, и краевые случаи.

Ключевой навык — оценить, пройдёт ли решение по времени. Если n доходит до 105–106, решение за O(n²) уже не уложится, и нужно искать линейный или логарифмический подход.

Разбор задач

Задача 1. Пара с заданной суммойхеш-таблица · за один проход

Дан массив из n целых чисел и число S. Нужно определить, есть ли в массиве два разных элемента, сумма которых равна S. Ограничение: n до 105.

Решение

Наивное решение — перебрать все пары — работает за O(n²). При n до 105 это около 1010 операций и по времени не проходит.

Идея: пройти массив один раз, храня уже встреченные числа в хеш-множестве. Для текущего элемента x проверяем, встречалось ли ранее число S − x.

Если S − x уже в множестве — пара найдена. Иначе добавляем x в множество и идём дальше.

Проверка в хеш-множестве и добавление — в среднем за O(1), поэтому весь алгоритм работает за O(n).

Краевые случаи: элементы должны быть разными по позиции — но так как мы проверяем S − x до добавления x, один и тот же элемент дважды не учитывается.

Ответ: Задача решается за один проход, O(n) по времени и O(n) по памяти.

«Искали пару перебором за O(n²)» почти всегда заменяется на «храним увиденное в множестве и ищем дополнение до суммы за O(1)».

Задача 2. Число способов подняться по лестницединамическое программирование

Лестница из n ступеней. За один шаг можно подняться на 1 или на 2 ступени. Сколько существует различных способов подняться с земли (0) на верхнюю ступень n?

Решение

Обозначим dp[i] — число способов добраться до ступени i. На ступень i можно попасть либо с i − 1 (шагом 1), либо с i − 2 (шагом 2).

Значит dp[i] = dp[i − 1] + dp[i − 2]. Это переход динамического программирования.

База: dp[0] = 1 (один способ «никуда не идти»), dp[1] = 1 (единственный шаг на 1).

Считаем по порядку. Для n = 5: dp[2] = 2, dp[3] = 3, dp[4] = 5, dp[5] = 8.

Ответ для n ступеней — dp[n]; последовательность совпадает с числами Фибоначчи. Время O(n), память можно сократить до двух последних значений — O(1).

Ответ: Число способов равно dp[n] по правилу dp[i] = dp[i−1] + dp[i−2]; для n = 5 это 8.

Классическая динамика: разбить путь по «последнему шагу». Если на состояние можно прийти несколькими способами — их числа складываются.

Задача 3. Суммы на отрезкахпрефиксные суммы · предподсчёт

Дан массив a из n чисел и q запросов вида «найти сумму элементов на отрезке от l до r». Нужно ответить на все запросы быстро. Ограничения: n и q до 105.

Решение

Отвечать на каждый запрос прямым суммированием — это до O(n) на запрос и O(n·q) суммарно, что при 105 запросах не проходит.

Идея: заранее посчитать префиксные суммы. Пусть p[0] = 0 и p[i] = a[1] + a[2] + … + a[i]. Тогда p считается за O(n) одним проходом: p[i] = p[i − 1] + a[i].

Сумма на отрезке [l; r] выражается через префиксы: sum(l, r) = p[r] − p[l − 1].

Каждый запрос теперь — одно вычитание, то есть O(1). Все q запросов — за O(q).

Краевой случай: для l = 1 используем p[0] = 0, поэтому отдельной обработки начала массива не требуется.

Ответ: Предподсчёт префиксных сумм за O(n), затем каждый запрос за O(1); суммарно O(n + q).

Если многократно спрашивают сумму на отрезках неизменного массива — почти всегда спасают префиксные суммы: sum(l, r) = p[r] − p[l−1].

Где взять реальные варианты

Реальные задачи прошлых лет с тестами и разборами публикуют организаторы олимпиад и агрегаторы. Прорешивать полезнее именно официальные варианты — по ним видно типичные ограничения и форматы.

Подготовиться к олимпиаде по информатике

В Олмат готовим к олимпиадам по информатике и программированию: алгоритмы и структуры данных, оценка сложности, разбор задач прошлых лет и работа над ошибками по вердиктам проверки. Первая консультация бесплатная.

Записаться на консультацию

Частые вопросы

На каком языке решать олимпиады по информатике?
Чаще всего на C++ — за скорость работы на больших тестах. Начинать можно на Python: он проще для входа, а идею алгоритма проверяет одинаково.
Почему наивное решение не проходит?
Обычно из-за времени. Если алгоритм работает за O(n²), а n доходит до 10⁵, это порядка 10¹⁰ операций — система выдаёт превышение времени. Нужен линейный или логарифмический подход.
Что важнее — знать алгоритмы или уметь их писать?
И то, и другое вместе: придумать идею, оценить сложность и аккуратно реализовать без ошибок в краевых случаях. Навык набирается практикой на тренажёрах.

Задачи в разборе — характерные учебные постановки для олимпиад по информатике; решения авторские. Официальные варианты и разборы по годам публикуют организаторы олимпиад (ссылки выше).