Причалы в час пик
Условие
В прибрежном городе запустили речные трамвайчики. У набережной есть несколько одинаковых причалов. Если два трамвайчика одновременно хотят стоять у одного причала — начинается хаос.
Каждый рейс занимает причал на полуинтервале времени [a, b): с момента a включительно и до момента b не включая b. Это значит, что если один рейс заканчивается ровно в момент t, а другой начинается ровно в момент t, то они могут использовать один и тот же причал.
Нужно понять, сколько причалов достаточно, чтобы расписание точно работало.
Формат ввода
В первой строке дано целое число n — количество рейсов. Далее в n строках записаны пары целых чисел a_i и b_i — время начала и конца рейса.
Формат вывода
Выведите одно целое число — минимальное количество причалов.
Ограничения
2 ≤ n ≤ 350000 ≤ a_i < b_i ≤ 1000000000
Пример
Ввод:
5
1 4
2 6
4 7
5 8
3 5
Вывод:
3Как решать — идея подхода
Приём: Сканирующая прямая (события + сортировка)
Ключевое наблюдение: сколько причалов нужно, зависит только от того, сколько рейсов одновременно занимают набережную. Если в какой-то момент пересекаются 3 рейса, меньше чем 3 причала не хватит; если максимум пересечений равен 3, то 3 достаточно.
Приём: события (sweep line). Вместо проверки всех пар интервалов превращаем каждый рейс [a, b) в два события: «пришёл» (+1) в момент a и «ушёл» (-1) в момент b. Идём по времени слева направо, поддерживаем текущую занятость и берём максимум.
Важно из-за полуинтервала [a, b): в момент b рейс уже не занимает причал, значит при одинаковом времени события должны обрабатываться так: уход раньше прихода.
План:
- Считать все пары (a, b).
- Создать массив событий:
(a, +1)и(b, -1). - Отсортировать события по времени, а при равном времени — по delta так, чтобы -1 шло раньше +1 (например, по ключу
(t, delta)). - Пройти по событиям:
cur += delta, обновлятьans = max(ans, cur). - Вывести ans.
Сложность: сортировка 2n событий, итого O(n log n) по времени и O(n) по памяти.
Частая ошибка: перепутать порядок при равных временах и посчитать, что рейс, начинающийся в t, конфликтует с рейсом, заканчивающимся в t. Проверь, что при t сначала идёт (-1), потом (+1).
Разберись руками
Есть 5 рейсов, каждый занимает причал на времени [a, b): старт включён, финиш не включён. Если один рейс заканчивается в момент t, а другой начинается в t, они могут быть на одном причале. Нужно понять, сколько причалов минимум надо для этого расписания.
- Начнём «руками». Какой рейс стартует самым ранним и точно будет первым, если идти по времени начала?
- Наивная идея (часто так делают по ошибке): «смотрим только на последний добавленный причал». После рейсов [1,4) и [2,6) у нас два причала с концами 4 и 6. Теперь приходит рейс [4,7). Если смотреть только на ПОСЛЕДНИЙ (конец 6), что решит наивный подход?
- А как правильно поступить с рейсом [4,7), если помнить, что интервалы полуоткрытые [a,b) и момент b уже свободен?
- Теперь доведи мысль до конца на всех 5 рейсах: если каждый раз пытаться переиспользовать причал, который освобождается РАНЬШЕ ВСЕХ (и уже свободен к началу рейса), сколько причалов в итоге достаточно для этого расписания?
Идея: Идём по рейсам по времени начала. Храним для каждого причала время, когда он освободится. Когда приходит новый рейс, стараемся поставить его на причал, который освобождается раньше всех и уже свободен к началу; если такого нет — открываем новый причал. Самое большое количество одновременно занятых причалов и будет ответом.
Решить задачу с автопроверкой на Python →
Куда дальше
- Школьный этап ВсОШ по информатике — как устроен первый этап и план подготовки за четыре недели
- Вердикты судьи: WA, TLE, RE, PE, CE — что значит каждый код проверяющей системы и где искать причину
- С нуля до олимпиады: маршрут — сколько занимает язык, какие приёмы нужны и к какому этапу это ведёт