В цивилизованных
странах на железнодорожном вокзале работают k
касс, однако очередь в них всего одна. Обслуживание происходит следующим
образом. Изначально, когда все кассы свободны, первые k человек из очереди подходят к кассам. Остальные ждут своей
очереди. Как только кто-нибудь будет обслужен и соответствующая касса
освободится, следующий человек из очереди подходит к этой кассе. Так
продолжается до тех пор, пока не будут обслужены все клиенты.
Определите
время, за которое будут обслужены все клиенты.
Вход. В первой строке
находится два целых числа: размер очереди n
и количество касс k (1 ≤ n ≤ 105, 1 ≤ k ≤ 104). Во второй
строке задаются n натуральных чисел. i-ое число определяет время ti (1 ≤ ti ≤ 105),
которое требуется для того, чтобы обслужить i-го
клиента из очереди.
Выход. Выведите одно
число – время, за которое будет обслужена заданная очередь.
Пример входа |
Пример выхода |
7 3 1 2 3
4 5 3 1 |
7 |
РЕШЕНИЕ
структуры данных – set, куча
Будем моделировать процесс продажи билетов при помощи
мультимножества s. Первые k людей подводим к свободным кассам –
заносим время их обслуживания в мультимножество. При дальнейшей обработке
мультимножество будет содержать k
элементов. Каждый их них отображает момент времени, в которое соответствующая
касса станет свободной и к ней сможет подойти следующий человек. Очевидно, что
каждый раз новый человек должен подходить к той кассе, для которой это время
минимально. Время последнего обслуженного клиента и будет искомым.
Рассмотрим
приведенный пример. Кладем в кучу k = 3 первых элементов.
Далее
на каждой итерации берем следующий элемент (следующего человека из очереди) и
кладем вместо наименьшего (человека ставим в ту очередь которая раньше
закончится). В очередь кладем время, в которое этот новый человек отойдет от
кассы. Возле каждого рисунка приведены числа, находящиеся в куче.
Информацию о моментах времени, в которые происходит
продажа билетов в кассах, храним в мультимножестве s.
multiset<long long> s;
Читаем входные данные. Время обслуживания первых k людей заносим в мультимножество s.
scanf("%d %d",&n,&k);
for(i = 0; i < n; i++)
{
scanf("%d",&ti);
if (s.size()
!= k) s.insert(ti);
else
{
Находим человека, который раньше всего отойдет от касс, и
ставим за ним следующего человека из очереди.
long long temp = *s.begin();
s.erase(s.begin());
s.insert(temp + ti);
}
}
Наибольшее число в мультимножестве s равно моменту времени, в который обслужится последний клиент. Оно
и будет искомым.
while(s.size() > 1) s.erase(s.begin());
printf("%lld\n",*s.begin());
Реализация через
очередь с приоритетами
Заведем кучу, в корне которой находится наименьший
элемент.
priority_queue<long long, vector<long long>,
greater<long long>
> pq;
Читаем входные данные. Время обслуживания первых k людей заносим в очередь pq.
scanf("%d %d",&n,&k);
for(i = 0; i < n; i++)
{
scanf("%d",&ti);
if (pq.size()
!= k) pq.push(ti);
else
{
Находим человека, который раньше всего отойдет от касс, и
ставим за ним следующего человека из очереди.
long long temp = pq.top(); pq.pop();
pq.push(temp + ti);
}
}
Наибольшее число в очереди pq равно моменту времени, в который обслужится последний клиент.
Оно и будет искомым.
while(pq.size() > 1) pq.pop();
printf("%lld\n",pq.top());
Java реализация
import java.util.*;
public class
Main
{
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
int n = con.nextInt();
int k = con.nextInt();
PriorityQueue<Long> pq = new PriorityQueue<Long>();
for(int i
= 0; i < n; i++)
{
long ti = con.nextLong();
if (pq.size() != k) pq.add(ti);
else pq.add(pq.poll() + ti);
}
while(pq.size() > 1)
pq.poll();
System.out.println(pq.poll());
}
}