Блог пользователя seland

Автор seland, 10 лет назад, перевод, По-русски

545A - Игрушечные машинки

Можно найти всю информацию о столкновениях i-той машинки в i-той строке матрицы A. А именно, если в i-той строке есть хотя бы одна из цифр 1 или 3, то i-тая машина не является хорошей (она перевернулась при каком-то столкновении). Иначе, i-тая машина — хорошая. Теперь нам просто нужно проверить это условие для каждой машинки.

545B - Равноудалённая строка

Можно заметить, что если si = ti для некоторого i, то значение pi для нас не важно. В самом деле, если pi равно si, то оно также равно и ti. И если pi не равно si, то оно также не равно и ti. Так мы получаем ответ, который одновременно ближе или дальше от обоих строк s и t.

Тогда нам интересны такие позиции i, что si ≠ ti. Если мы положим pi равным si мы увеличим расстояние от p до t. Если мы положим pi равным ti то мы увеличим расстояние от p до s. Это означает, что нам необходимо разделить эти позиции на две равные по количеству группу, чтобы получить равноудалённую строку. Например, мы можем сделать так, чтобы первая из этих позиций была ближе к s, вторая к t и т.д. Если таких позиций чётное количество, то мы получим ответ, если нечётное, то ответа не существует.

Временная сложность — O(n).

545C - Дровосеки

Задачу можно решить с помощью динамического программирование или с помощью жадного алгоритма. Начнём с динамики.

Обозначим через stayi, lefti and righti наибольшее количество деревьев, которые дровосеки могут повалить, если существует только деревья с номерами с 1 по i, и i-тое дерево не срублено, i-тое дерево срублен и повалено влево, i-тое дерево срублено и повалено вправо соответственно. Теперь мы можем посчитать эти значения для каждого i от 1 до n за O(n) времени, потому что для вычисления каждой следующей величины нам нужно только две предыдущих. Ответом будет наибольшее из stayn, leftn, rightn.

Также эту задачу можно было решить жадным алгоритмом. Давайте повалим самое левое дерево влево (это никогда не ухудшает ответ). После этого, попробуем повалить следующее дерево. Если мы можем повалить его влево, сделаем это (потому что это также никогда не ухудшает ответ). Если не можем, тогда пробуем повалить вправо. Если это возможно, делаем это. Последний шаг справедлив, потому что сваливание некоторого дерева вправо может помешать только сваливанию следующего дерева. Так что мы можем "обменять" одно дерево на другое, не ухудшив ответа.

Временная сложность — O(n).

545D - Очередь

Можно решить задачу с помощью жадного алгоритма. Докажем, что всегда можно найти ответ (очередь с наибольшим числом довольных людей), в которой все довольные люди стоят вначале очереди. Предположим противное — существует позиции i и j, такие что i < j, все люди с i-го по j - 1-го недовольны, а j-тый человек доволен. Тогда просто поменяем местами людей на позиции i и j. После этого люди на с i-го по j - 1 будет по-прежнему недовольными (или некоторые станут довольными), а j-тый будет по-прежнему довольным. Таким образом, ответ не ухудшился.

Значит, нам нужно находить человека с минимальным ti, который можно обслужить сейчас и он будет доволен. Это можно сделать, отсортировав всех людей по возрастанию ti и пробуя обслуживать их по очереди. Если кто-то будет недоволен, можно отправить его в конец очереди и не добавлять время на его обслуживание к текущему времени ожидания.

Временная сложность — — O(n + sort).

545E - Пути и деревья

Это правда, что модификация алгоритма Дейкстры, в которой среди разных расстояний выбирают то, в котором последнее ребро минимально, даёт правильный ответ.

Чтобы доказать это, немного модифицируем граф. Для начала найдём кратчайшие пути из u до каждой вершины. Обозначим через di длины кратчайшего пути из u в i. После этого можем удалить некоторые рёбра. Конкретнее, мы можем удалить ребро с концами x и y и весом w если |dx - dy| ≠ w, потому что оно не содержится ни в одном кратчайшем пути, а значит не содержится и в дереве кратчайших путей. После этого можем ориентировать рёбра от вершин с меньшим d в вершину с большим (потому что веса рёбер положительны). Легко доказать, что если взять по одному входящему ребру в каждую вершину, то эти рёбра будут образовывать дерево кратчайших путей. Тогда нам достаточно взять для каждой вершины, входящее в неё ребро минимального веса. Почему? Потому что мы должны взять хотя бы по одному ребру, входящему в каждую вершину, чтобы получить связный граф. Мы не можем взять ребра с меньшим весом, чем минимальное. И если мы возьмем минимальные рёбра мы также получим дерево кратчайших путей. Так что это и есть дерево кратчайших путей с минимальным суммарным весом.

Можно заметить, что такая модификация алгоритма Дейкстры выполняет точно такие же действия.

Time complexity —

Полный текст и комментарии »

Разбор задач Codeforces Round 303 (Div. 2)
  • Проголосовать: нравится
  • +38
  • Проголосовать: не нравится

Автор seland, 10 лет назад, По-русски

Всем привет!

Рад сообщить, что скоро состоится Codeforces Round #303 для участников Div.2, автором которого являюсь я. Как всегда, участники Div.1 могут поучаствовать вне конкурса.

Это мой первый раунд, и я надеюсь, что он будет для Вас интересным.

Раунд не состоялся бы без помощи команды Codeforces! Спасибо Zlobober за помощь в подготовке раунда и Delinur за перевод. Отдельное спасибо всем, кто вложил силы в создание и поддержку систем Codeforces и Polygon.

Распределение баллов будет объявлено позже.

Удачи и вдохновения!

UPD Распределение баллов по задачам — 500-1000-1750-1750-2500.

UPD Поздравляем победителей в официальном зачёте:

  1. Bell-sama
  2. anko
  3. BobDylan
  4. Gusheng
  5. Diguised
  6. imyyimdog

И в неофициальном зачёте:

  1. ngfam_kongu
  2. Laakeri
  3. Um_nik
  4. KrK

UPD Ссылка на разбор.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +174
  • Проголосовать: не нравится

Автор seland, 10 лет назад, По-русски

Что-то сегодня было не так с добавлением задач, или что-то не так со мной. При добавление задачи в мешап по ссылке из дескриптора контеста, скачанного с Полигона, выдаёт ошибку: "Невозможно найти/получить дескриптор задачи".

Пробую создавать тренировку — действую как написано в инструкции справа. В итоге получаю несколько неожиданностей — во-первых, при нажатии на обновление контеста меня перебрасывало на другие страницы Codeforces, которые были открыты в том же браузере. Но, что более грустно, так и не получилось создать тренировку. Говорит:

"Не удалось выпустить релиз соревнования из-за ошибок валидации: Can't download statement of contest from 'https://polygon.codeforces.com/c/2420/ukrainian/statements.pdf': Received unexpected Response {code=403, size=961, s='<ti...body>'}."

При этом пакеты всех задач из контеста были готовы.

Еще одной неприятностью для меня стала невозможность удалять файлы из корня песочницы и невозможность удалять папки в принципе.

В общем, хотелось бы всё-таки понять, что случилось, и как создать тренировку.

Буду благодарен за помощь в этом вопросе!

Полный текст и комментарии »

  • Проголосовать: нравится
  • +4
  • Проголосовать: не нравится