Кто на табло?
Условие
На школьном турнире несколько классов набирают очки. После каждого события (кому-то добавили очки) табло подсвечивает лидера — класс с наибольшей суммой очков. Если лидеров несколько (ничья по максимуму), табло подсвечивает класс с меньшим номером.
Тебе дали запись всех событий. Посчитай, сколько раз менялся подсвеченный лидер, если сравнивать табло после соседних событий: между 1-м и 2-м, между 2-м и 3-м, ..., между (n−1)-м и n-м.
Формат ввода
В первой строке два целых числа k и n — число классов и число событий. Далее идут n строк, в каждой: c и p — номер класса, которому добавили очки, и сколько очков добавили.
Формат вывода
Выведите одно целое число — сколько раз менялся подсвеченный лидер между соседними событиями.
Ограничения
1 ≤ k ≤ 20001 ≤ n ≤ 20001 ≤ c ≤ k0 ≤ p ≤ 1000000
Пример
Ввод:
3 5
2 2
3 2
2 1
1 5
3 10
Вывод:
2Как решать — идея подхода
Приём: Симуляция + поиск максимума
Ключевое наблюдение: табло после каждого события зависит только от текущих сумм очков классов. Значит, можно честно «проиграть» все события по порядку.
Приём: симуляция (пошаговое обновление состояния) + поиск максимума. Ограничения маленькие (k, n ≤ 2000), поэтому пересчитывать лидера полным просмотром всех классов после каждого события успевает.
План:
- Заведи массив
scores[1..k], сначала все нули. - Держи
prev_leader— кто был подсвечен после предыдущего события. - Для каждого события (c, p):
- сделай
scores[c] += p. - найди текущего лидера: класс с максимальным
scores[i], а при равенстве — с меньшим номером. - удобно обновлять так:
if s > best or (s == best and i < best_id): ... - если это не первое событие и лидер изменился (
best_id != prev_leader), увеличь счётчик смен. - присвой
prev_leader = best_id. - Выведи счётчик.
Сложность: O(n * k) по времени (до 4 млн сравнений) и O(k) по памяти.
Частая ошибка: засчитать «первого лидера» как смену. Смены считаются только между соседними событиями, поэтому сравнение начинается со 2-го события.
Разберись руками
Есть 3 класса (1, 2, 3) и 5 событий, где кому-то добавляют очки. После каждого события табло показывает лидера: у кого очков больше; если максимум делят несколько — выбирают меньший номер.
- Проиграй 5 событий по очереди. Начало: у всех 0 очков. После каждого события запиши новое состояние в формате: "1=...,2=...,3=... | leader=...". Важно: если максимум вничью — лидер тот, у кого номер меньше.
- Теперь отметь номера «переходов» между соседними событиями, где лидер поменялся. Переход 1 — между 1-м и 2-м событием, переход 2 — между 2-м и 3-м, ... Всего переходов 4 (от 1 до 4).
- Сколько всего раз лидер менялся между соседними событиями?
Идея: Сначала честно симулируй события: обновляй очки нужного класса и каждый раз заново определяй лидера (при ничьей по максимуму выбирай меньший номер). Записывай лидера после каждого события, а потом сравнивай соседние записи и считай, сколько раз они разные.
Решить задачу с автопроверкой на Python →
Куда дальше
- С нуля до олимпиады: маршрут — сколько занимает язык, какие приёмы нужны и к какому этапу это ведёт
- Перечневые олимпиады по информатике — олимпиады перечня Минобрнауки, их уровни и что нужно к диплому
- БВИ по олимпиадам: в какие вузы берут — правила приёма вузов, разобранные построчно, со ссылкой на приказ у каждой строки