Столовая и звонок
Условие
На перемене в школьной столовой выстроилась очередь из n учеников. Все подошли одновременно и стоят строго в заданном порядке.
На кассе обслуживают по одному и без перерывов: сначала первого, потом второго и т. д. На обслуживание i-го ученика нужно a[i] секунд.
Звонок на урок прозвенит ровно через B секунд после начала перемены. Успевшими считаются только те, чьё обслуживание полностью закончилось не позже звонка.
Нужно узнать: 1) сколько учеников успеют полностью обслужиться; 2) сколько секунд останется до звонка после того, как обслужат последнего из успевших (если не успеет никто — это просто B).
Формат ввода
В первой строке два целых числа n и B. Во второй строке n целых чисел a[1], a[2], ..., a[n].
Формат вывода
Выведите два целых числа: k и r, где k — число учеников, которых успели обслужить полностью, а r — сколько секунд осталось до звонка после обслуживания последнего из них.
Ограничения
1 ≤ n ≤ 20001 ≤ B ≤ 10001 ≤ a[i] ≤ 1000
Пример
Ввод:
5 12
2 5 4 3 1
Вывод:
3 1
В этом примере успеют обслужить первых трёх (2+5+4=11 секунд), после этого до звонка останется 12−11=1 секунда.
Как решать — идея подхода
Приём: Симуляция с накоплением времени
Ключевое наблюдение: порядок фиксирован, касса работает без пауз, значит момент окончания обслуживания каждого ученика — это просто сумма a[1] + ... + a[i]. Успеют ровно первые k учеников, для которых эта сумма не превышает B.
Здесь подходит простая симуляция (пошаговый подсчёт), потому что каждое решение «успеет/не успеет» зависит только от уже накопленного времени и длительности текущего ученика.
План решения:
- Заведи переменные:
t = 0(сколько секунд уже потрачено) иk = 0(сколько учеников успели). - Иди по массиву
aслева направо. - Для очередного
x = a[i]проверь: еслиt + x <= B, то ученик успевает: сделайt += x,k += 1. - Иначе дальше никто не успеет (они стоят после него), поэтому можно сразу остановиться.
- Остаток времени до звонка после последнего успевшего:
r = B - t. Если не успел никто, тоt = 0, и формула всё равно дастr = B.
Мини-сниппет проверки:
if t + x <= B: t += x; k += 1 else: break
Сложность: O(n) по времени, O(1) по памяти.
Частая ошибка: считать успевшими тех, кто «начал обслуживаться до звонка». По условию нужно, чтобы обслуживание полностью закончилось не позже B, поэтому проверка именно t + a[i] <= B.
Разберись руками
В очереди 5 учеников. Звонок будет через 12 секунд. Время обслуживания по порядку: 2, потом 5, потом 4, потом 3, потом 1 секунду.
- Проиграем обслуживание по очереди. Состояние — сколько секунд уже прошло с начала перемены. После каждого события напиши новое число секунд (если на каком-то шаге следующий не успевает до 12, то время «замораживается», потому что мы останавливаемся).
- Сколько учеников успели полностью обслужиться до звонка (до 12 секунд включительно)?
- Сколько секунд осталось до звонка после обслуживания последнего успевшего?
Идея: Идём по очереди и накапливаем, сколько времени уже потратили. После каждого ученика проверяем, что обслуживание закончится не позже звонка; если следующий уже не помещается — сразу останавливаемся. Потом берём, сколько человек успели, и сколько времени осталось до звонка после последнего из них.
Решить задачу с автопроверкой на Python →
Куда дальше
- С нуля до олимпиады: маршрут — сколько занимает язык, какие приёмы нужны и к какому этапу это ведёт
- Вердикты судьи: WA, TLE, RE, PE, CE — что значит каждый код проверяющей системы и где искать причину
- Python на олимпиадах — где языка хватает с запасом, а где начинают значить лимиты — с замерами