Слишком близкие результаты
Условие
На школьных соревнованиях по бегу судья хочет понять, сколько пар участников показали «почти одинаковый» результат.
Результат каждого участника — целое число (например, время в миллисекундах). Пара участников считается «почти одинаковой», если разница их результатов не больше D.
Посчитайте, сколько существует пар участников (i, j), где i < j, таких что |a[i] - a[j]| ≤ D.
Важно: значения и ответ могут не помещаться в 32-битный тип (как на олимпиадах), используйте 64-битную арифметику. В Python это уже учтено.
Формат ввода
В первой строке записаны два целых числа n и D. Во второй строке записаны n целых чисел a1, a2, ..., an — результаты участников.
Формат вывода
Выведите одно целое число — количество пар (i, j), i < j, для которых |ai - aj| ≤ D.
Ограничения
2 ≤ n ≤ 350000 ≤ D ≤ 2_000_000_000-1_000_000_000 ≤ ai ≤ 1_000_000_000
Пример
Ввод:
5 3
1 2 10 4 7
Вывод:
5
Подходящие пары по значениям: (1,2), (1,4), (2,4), (4,7), (7,10).
Как решать — идея подхода
Приём: Сортировка + два указателя
Ключевое наблюдение: условие |a[i] - a[j]| ≤ D неудобно в исходном порядке, но после сортировки всё упрощается. Если a отсортирован, то для i < j разность просто a[j] - a[i] (она уже неотрицательная), и для фиксированного i подходят подряд идущие j: как только разница стала больше D, дальше (при большем j) она уже не уменьшится.
Здесь работает приём «два указателя» (скользящее окно): правая граница j никогда не двигается назад, поэтому общий проход получается линейным.
План:
- Отсортировать массив
a. - Завести
j = 0иans = 0. - Для каждого
iслева: - сделать
j = max(j, i+1). - пока
j < nиa[j] - a[i] ≤ D, увеличиватьj. - все индексы
i+1 ... j-1дают подходящие пары сi, добавить их количество:ans += (j - i - 1). - Вывести
ans(в Python тип int уже «64-бит+»).
Сложность: сортировка O(n log n) и один линейный проход O(n), память O(1) сверх массива.
Частая ошибка: сбрасывать j в i+1 на каждом шаге без max(...) или двигать j назад — это легко превращает решение в O(n^2).
Разберись руками
Есть 5 результатов: 1, 2, 10, 4, 7. Разница считается «почти одинаковой», если она не больше 3. На этом примере руками найдём все подходящие пары через два указателя.
- Сначала удобнее отсортировать результаты. Отметь на ленте от 1 до 10 числа, которые получатся после сортировки списка: 1 2 10 4 7.
- Теперь два указателя: i (левый) и j (правый). Список: [1, 2, 4, 7, 10], D = 3. Для каждого i двигай j вправо, пока разница (текущее значение j) - (значение i) не станет больше 3. После этого добавь к ответу, сколько элементов между i и j подходят (то есть сколько пар получилось с этим i). Заполни состояние после каждого i.
- Какое итоговое количество пар получилось на примере (total в конце)?
Идея: Отсортируй результаты. Держи два указателя: левый перебирает элементы по очереди, а правый уходит вправо настолько далеко, насколько ещё сохраняется «разница не больше нужного числа». Для каждого левого указателя добавляй к ответу, сколько правых позиций подошло, и не возвращай правый указатель назад.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- Перечневые олимпиады: что это и что дают — весь перечень Минобрнауки: уровни, срок диплома, разрезы по предметам и классам
- Олимпиада по информатике: с чего начать — два мира олимпиад — ВсОШ и перечневые: этапы, задания и на каком языке писать