Дуэты для арены: не перегрузи сервер
Условие
В игре открыли «арену дуэтов». Игроки заходят парами, но у сервера есть лимит: если сумма сил двух игроков в паре больше L, сервер перегружается и такая пара не допускается.
Каждый игрок может попасть на арену не более одного раза. Хочется пустить на арену как можно больше дуэтов.
Посчитайте максимальное число допустимых дуэтов.
Формат ввода
Первая строка: два целых числа n и L — число игроков и лимит сервера. Вторая строка: n целых чисел a1, a2, ..., an — силы игроков.
Формат вывода
Выведите одно целое число — максимальное количество дуэтов.
Ограничения
1 ≤ n ≤ 500001 ≤ L ≤ 2 000 0001 ≤ ai ≤ 1 000 000
Пример
Ввод:
6 10
1 2 3 7 8 9
Вывод:
3Как решать — идея подхода
Приём: Жадный алгоритм + два указателя
Ключевое наблюдение: чтобы сделать максимум пар с ограничением по сумме, сильных игроков «опасно» тратить на средних — лучше пытаться пристроить каждого сильного к самому слабому, который ещё подходит. Если даже с самым слабым сильный не проходит по лимиту, то он не пройдёт ни с кем (все остальные только сильнее), значит его можно смело исключить.
Приём: жадность с двумя указателями после сортировки. Это работает, потому что выбор для самого сильного игрока максимально ограничен: либо он идёт в пару с самым слабым (если помещаются), либо не идёт вообще. Любая другая попытка «спасти» сильного только ухудшит шансы слабых собрать пары.
План:
- Отсортировать массив сил по возрастанию.
- Поставить i на начало (самый слабый), j на конец (самый сильный), ответ = 0.
- Пока i < j:
- Если
a[i] + a[j] <= L, засчитываем дуэт, делаемi += 1,j -= 1. - Иначе пара с j невозможна ни с кем, уменьшаем
j -= 1. - Вывести ответ.
Сложность: сортировка O(n log n), проход двумя указателями O(n), памяти O(1) кроме массива.
Частая ошибка: при a[i] + a[j] > L двигать i (теряя слабого зря). Нужно двигать j, потому что проблема в слишком сильном игроке.
Разберись руками
Есть 6 игроков с силами 1, 2, 3, 7, 8, 9. Лимит сервера 10: в дуэт можно пустить только если сумма сил пары не больше 10. Каждый игрок может быть в дуэте максимум один раз — нужно получить как можно больше дуэтов.
- Возьмём самого сильного игрока 9. На ленте 1..9 отметь силы, которые МОГУТ быть его напарником, чтобы сумма не превысила 10.
- Мы сделали дуэт (9,1). Остались силы 2, 3, 7, 8. Теперь самый сильный — 8. Какого напарника выгоднее взять, чтобы не тратить “слабых” зря, но уложиться в лимит 10?
- Остались только силы 3 и 7. Что делаем?
- Сколько всего дуэтов получилось в этом примере?
Идея: Сортируем силы и каждый раз смотрим на самого сильного оставшегося игрока: пытаемся подобрать ему самого слабого, с которым лимит не превышается. Если даже с самым слабым не проходит — этот сильный игрок ни с кем не сможет пройти, значит его надо пропустить и пробовать следующего сильного. Так собираем максимум дуэтов.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- На программиста по олимпиаде: путь по классам — что даёт диплом, куда с ним берут на ИТ-направления и почему решает 9 класс
- Вердикты судьи: WA, TLE, RE, PE, CE — что значит каждый код проверяющей системы и где искать причину