Задача A. Double Cola
Обозначим персонажей по первой букве имени. Очередь имеет вид: Ш-Л-П-Р-Г, через 5 баночек: Ш-Ш-Л-Л-П-П-Р-Р-Г-Г, еще через 10 баночек: Ш-Ш-Ш-Ш-Л-Л-Л-Л-П-П-П-П-Р-Р-Р-Р-Г-Г-Г-Г.
Закономерность ясна, и решение очень простое: будем итерироваться по p - найдем такое минимальное p, что 5· 2p > n (при этом, если это число меньше или равно, то вычтем из n его), тогда мы знаем, что у нас сначала стоят 2p Шелдонов, потом 2p Леонардов и так далее. И теперь мы можем легко ответить, кто же взял баночку номер n (а именно это был человек с номером n / 2p в массиве Ш-Л-П-Р-Г (в 0-индексации).
Задача B. Множества
Для решения нам понадобится следующий важный факт: допустим элементы v и u находятся в одном множестве, тогда в любой из n· (n - 1) / 2 последовательностей из входных данных, где встречается v обязательно встречается u. А также, если v и u --- в разных множествах, то существует такая последовательность, в которой есть v, но нет u. Тогда можно ввести отношение эквивалентности для всех элементов всех множеств --- два элемента эквивалентны, если не существует последовательности, где один элемент встречается, а другой нет. Классы эквивалентности и есть искомые множества.
Считать ответ можно было следующим алгоритмом: выпишем для каждого числа список номеров последовательностей, где встречается это число, и объединим два числа, если эти списки равны. Этот алгоритм можно реализовать за O(n2 * log(n)), впрочем, решение за O(n3)
тоже проходит все тесты с большим запасом времени.
Особый случай - это тест с n = 2. Именно этот тест использовался для большого количества взломов.
Задача C. Всеобщая мобилизация
Сначала оценим сверху максимальное время, к которому все дивизии доберутся до столицы - очевидно, для этого требуется не более n дней. Поэтому ограничения вполне позволяли промоделировать движения дивизий. Ключевой момент решения - будем всегда рассматривать дивизии в порядке приоритета. Тогда в каждый день рассмотрим список тех дивизий, кто еще не дошел до столицы, и в порядке приоритета будем сажать на нужный поезд. Если поезд уже заполнен, то дивизия остается в текущем городе, иначе изменим ее положение, и в день, когда дивизия доберется до столицы запишем ответ. Итого: всего дней, которые нужно промоделировать, не более n, и каждый день мы передвигаем не более n дивизий. Значит, наше решение имеет асимптотику не более O(n2).
Решения, использующие различные структуры данных (сеты, очереди с приоритетами и т.д.), работают за O(n2· log(n)), и это не всегда укладывалось в TL.
Задача D. Два из трех
Задача решается динамическим программированием. Рассмотрим состояние (i, j), означающее, что в текущей очереди стоит человек номер i, а также все люди от j до n включительно. Любая очередь, достижимая из начальной, может быть представлена соответствующим состоянием. Количество состояний - O(n2), количество переходов - всего 3, то есть O(1). Значит, итоговая асимптотика - O(n2).
Задача E. Коридор
Эта задача имеет несколько решений, основанные на различных методах поиска площади объединения фигур на плосткости. Одним из таких методов является метод вертикальной декомпозиции (подробнее Вы можете почитать в различных статьях), а также можно было заметить, что среди фигур не существует трех, имеющих ненулевое пересечение, и поэтому достаточно было научиться находить общую площадь двух фигур. Для этого также можно было использовать различные методы, например, авторское решение основано на алгоритме отсечения выпуклого многоугольника полуплоскостью. Авторами предполагалось решение за O(n2).
Достаточно хранить не все списки а только 2 числа FIRST и SECOND - номер последовательности в которой число встретилось первый раз, и второй.
Эти числа считаются по мере считывания данных. (т.е. после обработки N^2 входных последовательностей).
Дальше если для двух чисел пары FIRST и SECOND совпадают, значит они лежат в одном множестве.
Сложность этого шага M^2 или M*logM (где M=200)
Т.е. решение можно сделать за чистый N^2 , без логарифма
если выводить множество как только оно встретилось второй раз то сложность линейна от входных даных
и как только нашли N множеств можно прекращать читать и завершатся.
(исключая случай N==2)т.е в лучшем случае достаточно прочитать N первых пар. в
Я во время контеста над этим очевидным думал минут 15-20
i dont get what the author is trying to say in problem A.can somebody please explain?
See my Submission 83246166
here you decremented n before dividing it, I'm confused why you did this step? int ans = (n -1)/ceil(pow(2,i));
Here is to subtract the queue from the previous group to get the number of queues in group I.