Расписание лекций Маши
बनाया गया: 29 दिसंबर 2024
बनाया गया: 29 दिसंबर 2024
Маша учится в школе, но безумно любит посещать открытые лекции в МГТУ им. Н.Э. Баумана. Маша старается всегда использовать своё свободное время максимально продуктивно, потому она заранее скачивает расписание преподавателей, чтобы посетить по лекции минимум 50% преподавателей в день, которые она выбрала.
Преподаватели читают одну и ту же лекцию несколько раз в день, в разные промежутки времени. Но у преподавателей есть негласное правило – можно опоздать на лекцию не больше, чем на 5 минут от начала. Можно уйти с лекции на 5 минут раньше.
Но иногда преподаватели разбросаны по расписанию очень сильно, иногда их время пересекается с другими. Поэтому Маше нужна помощь, чтобы по входному расписанию преподавателей определить, во сколько ей нужно быть в университете, чтобы посетить лекции минимум 50% преподавателей (если преподавателей нечётное количество, то округляем вверх (1 округляется до 1, 3 до 2 и так далее), а также провести минимальное количество времени в ожидании между лекциями (если они не подряд).
Входные данные:
На первой строке подаётся целое число N (1 <= N <= 100) – количество преподавателей, на лекции которых хочет сходить Маша.
Далее подаётся N наборов строк в виде:
· на одной строке указывается количество занятий для i-го преподавателя N_i (1 <= N_i <= 50);
· на N_i строках далее указываются временные промежутки занятий преподавателя (без самопересечений) в виде hh:mm-hh:mm (например, 09:10-10:15).
Выходные данные
На первой строке выведите, в какое время начнётся первая пара, на которую придёт Маша.
На второй строке выведите общее количество в минутах, которое Маша проведёт на лекциях.
На третьей строке выведите общее количество в минутах, которое Маша проведёт между лекциями.
Примечание:
· для удобства расчёта считаем, что путь с одной лекции до другой не занимает времени;
· время лекции у одного преподавателя всегда одинаковое;
· гарантируется, что Маша сможет посетить лекцию минимум 50% преподавателей;
· если задача имеет несколько ответов, то вывести тот, при котором Маша приедет как можно раньше;
· Маша пытается приехать как можно раньше, поэтому, как только она посетит 50% преподавателей, то она может уезжать домой, но приоритетом в задаче является в первую очередь минимальное время проведённое в ожидании между занятиями.
Входные данные
Выходные данные
3
2
10:05-11:50
17:00-18:45
1
11:45-12:30
2
13:00-14:00
16:00-17:00
10:05
145
0
Маше требуется посетить лекции 50% преподавателей, поэтому достаточно посетить 2 преподавателей. Маша пытается найти самое минимальное время для ожидания между занятиями. В данном случае возможны два варианта, когда Маша проведёт между занятиями 0 минут времени:
· посетив лекцию третьего преподавателя 16:00-17:00 и первого 17:00-18:45;
· посетив лекцию первого преподавателя 10:05-11:50 и второго 11:45-12:30.
Так как время ожидания между лекциями одинаковое, то выбираем тот вариант, при котором Маша приедет как можно раньше – 10:05.
Для решения данной задачи необходимо выбрать минимум 50% преподавателей, посещая по одной лекции от каждого, при этом минимизируя общее время ожидания между лекциями и выбирая наиболее раннее время начала первой лекции в случае равенства условий.
Парсинг входных данных:
N
.Ni
и сами временные интервалы лекций.Сортировка лекций:
Выбор оптимального набора лекций:
K = ceil(N / 2)
– минимальное количество преподавателей, которых необходимо посетить.K
лекций, начиная с этой, следуя условиям:
Вычисление итоговых значений:
pythonimport sys import math def time_to_minutes(t): h, m = map(int, t.split(':')) return h * 60 + m def minutes_to_time(m): h = m // 60 m = m % 60 return f"{h:02d}:{m:02d}" def main(): import sys import math input = sys.stdin.read data = input().splitlines() idx = 0 N = int(data[idx].strip()) idx +=1 lectures = [] for teacher_id in range(N): Ni = int(data[idx].strip()) idx +=1 for _ in range(Ni): time_str = data[idx].strip() idx +=1 s, e = time_str.split('-') s_min = time_to_minutes(s) e_min = time_to_minutes(e) lectures.append({'start':s_min, 'end':e_min, 'teacher':teacher_id}) # Sort lectures by start time, then by end time lectures.sort(key=lambda x: (x['start'], x['end'])) K = math.ceil(N / 2) best_total_waiting_time = math.inf best_start_time = math.inf best_total_lecture_time = 0 for i in range(len(lectures)): start_lecture = lectures[i] path = [start_lecture] selected_teachers = set() selected_teachers.add(start_lecture['teacher']) total_waiting_time = 0 total_lecture_time = start_lecture['end'] - start_lecture['start'] last_end_time = start_lecture['end'] for j in range(i+1, len(lectures)): lec = lectures[j] if lec['teacher'] in selected_teachers: continue if lec['start'] >= last_end_time -10: waiting_time = max(lec['start'] - last_end_time, 0) path.append(lec) selected_teachers.add(lec['teacher']) total_waiting_time += waiting_time total_lecture_time += (lec['end'] - lec['start']) last_end_time = lec['end'] if len(path) == K: break if len(path) == K: if (total_waiting_time < best_total_waiting_time) or (total_waiting_time == best_total_waiting_time and start_lecture['start'] < best_start_time): best_total_waiting_time = total_waiting_time best_start_time = start_lecture['start'] best_total_lecture_time = total_lecture_time # Output print(minutes_to_time(best_start_time)) print(best_total_lecture_time) print(best_total_waiting_time) if __name__ == "__main__": main()
Функции time_to_minutes
и minutes_to_time
: Преобразуют время из формата hh:mm
в минуты с начала дня и обратно.
Основная логика:
start
, end
и teacher
.K
лекций, соблюдая условия задачи.Вывод:
Для приведенного в задаче примера входных данных программа выведет:
text10:05 145 0