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

436A - Feed with Candy

Автор разбора: Fefer_Ivan

В задача А типы съеденных конфет должны все время менятся. Так что первая съеденная конфета определяет тип всех последующих конфет. Возможных типа всего два, так что переберем тип первой съеденной конфеты. Пусть в какой-то момент времени Ом Ном должен съесть конфету типа t и может прыгать на высоту h. Очевидно, что наиболее выгодным решением будет съесть конфету с наибольшей массой среди всех конфет, которые Ом Ном может съесть на текущем этапе. Для решения задачи необходимо промоделировать процесс поедания конфет для начального h = x и t = [0, 1] и выбрать лучшее значение.

436B - Om Nom and Spiders

Автор разбора: Fefer_Ivan

Пронумеруем столбцы таблицы начиная с 0 слева направа, а строки начиная с 0 сверху вниз. Теперь заметим, что в момент времени t > 0 в клетке (x, y) могут находиться только 4 паука:

  • Паук, который движется влево и в начале был в клетке (x, y + t).
  • Паук, который движется вправо и в начале был в клетке (x, y - t).
  • Паук, который движется вниз и в начале был в клетке (x - t, y).
  • Паук, который движется вверх и в начале был в клетке (x + t, y).

Давайте переберем столбец в котором Ом Ном начнет свой путь. Пусть это столбец y. В момент времени 0 все пауки стоят на своих исходных позициях, а Ом Ном стоит в клетке (0, y). Так как на нулевой строке нет пауков, то в момент времени 0 Ом Ном их точно не встречает. Когда Ом Ном находится в клетке (x, y), это значит, что с момента начала движения прошло x единиц времени. Следовательно, для того, чтобы вычислить сколько пауков Ом Ном встретим в этой клетке, необходимо проверить лишь 4 клетки, указанные выше, на наличие паука, движущегося в нужном направлении.

436C - Dungeons and Candies

Автор разбора: Fefer_Ivan

Давайте рассмотрим неориентированный взвешенный граф, в котором k + 1 вершина. Пронумеруем вершины целыми числами от 0 до k. Вершины c 1 по k будут соответствовать уровни. Для каждой пары уровней i и j добавим ребро из i в j стоимость которого равно стоимости передачи одного уровня как разность с другим. Так же для каждого уровня i добавим ребро между вершиной 0 и i стоимости n·m, т.е. стоимости передачи уровня целиком. Каждый способ передать все уровни соответсвует остовному дереву в указанном графе. Таким обзаром необходимо вывести минимальное остовное дерево в этом графе.

436D - Pudding Monsters

Автор разбора: Fefer_Ivan

Задача решается при помощи динамического программирования. Введем обозначения: sum(l, r) — количество особых клеток на отрезке с l по r, zi — максимальное количество особых клеток, которые можно покрыть, используя только первые i монстров при условии, что i-тый монстр либо остается на месте, либо отправляется влево, di--- максимальное количество особых клеток, которые можно покрыть, используя только первые i монстров при условии, что i-тый монстр остается на месте.

Рассмотрим процесс вычисления di. Пусть i-тый монстр находится в клетке r. Переберем самую левую особую клетку, которая будет покрыта блоком монстров, в котором будет находиться i-й монстр. Пусть эта особая клетка находится в клетке l. Тогда нам требуется r - l дополнительных монстров отправить вправо для того, чтобы покрыть эту особую клетку. Тогда ответ будет равен zi - (r - l) + sum(l, r). Для вычисления di надо взять максимум по всем особым клеткам, левее i-того монстра.

Теперь, после того, как мы вычислили очередное значение di, необходимо обновить некоторые значения zj. Пусть i-тый монстр находится в клетке l. Переберем самую правую особую клетку, которая будет покрыта блоком монстров, в котором будет находиться i-й монстр. Пусть эта особая клетка находится в клетке r. Тогда нам требуется r - l дополнительных монстров отправить влево для того, чтобы покрыть эту особую клетку. Тогда, zi + (r - l) можно обновить следующим значением di + sum(l + 1, r). Так же необходимо не забыть обновить значение zi значением zi - 1.

Как можно видеть это решение имеет сложность O(n·m), так как для каждого из n монстров мы перебираем все m особых клеток, а все вычисления при фиксированной паре монстр-клетка проходят за O(1).

При реализации могут возникнуть небольшие тонкости, связанные с монстрами, которые уже в начальном состоянии слиплись в один блок.

436E - Cardboard Box

Автор разбора: Gerald

В задаче E нужно было написать правильную жадность. Правильных жадностей существует несколько, вот одна из них:

  • Посмотрим на некоторый оптимальный ответ (набор как-то пройденных уровней). Отсортируем все уровни по b[i]. Если рассмотреть последний взятый в ответ уровень, пройденный на 2 звезды, то окажется, что все находящиеся до него в таком порядке уровни пройдены хотя бы на одну звезду. Иначе, можно было бы заменить этот уровень на какой-то не пройденный и не увеличить ответ.
  • Пользуясь вышесказанным, зафиксируем префикс L уровней в порядке сортировки по b[i]. Все уровни этого префикса мы должны хоть как-то пройти (либо на 1, либо на 2 звезды). Дополнительно, будет считать, что все уровни пройденные на 2 звезды должны содержаться только в этом префиксе (такой префикс должен существовать для некоторого оптимального ответа, как было показано ранее).
  • Так как мы зафиксировали префикс длиной L уровней, которые мы точно хоть как-то пройдем, можно сказать, что нам осталось добрать w - L звезд. Как мы можем добирать эти звезды? Либо допроходить какие-то уровни из префикса L на 2 звезды, либо проходить уровни не из префикса L на одну (потому что уровни, которые мы проходим на 2 звезды должны содержаться только на зафиксированном префиксе).
  • Понятно, что для того, чтобы получить оптимальный ответ нужно выбрать w - L самых дешевых звезд. Поэтому отсортируем n элементов: L чисел b[i] - a[i] (для всех i ≤ L), n - L чисел a[i] (для всех i > L). Выберем среди этих чисел w - L минимальных.

Описанное нужно было реализовывать быстрее, чем за квадрат. Самая очевидная реализация использует декартово дерево, чуть менее очевидная использует дерево отрезков.

Итоговая сложность решения: O(n log n).

436F - Banners

Автор разбора: Gerald

Задача F была самой сложной задачей контеста. Чтобы лучше представить себе ее решение, можно перейти к геометрическому представлению задачи. Представим, что люди — это точки на плоскости Opc, тогда, то что требуется найти — для каждой прямой c = i, такую прямую p = j, что некоторая функция принимает максимальное значение. Под некоторой функцией понимается следующая: (количество точек не ниже прямой c = i умножить на w·i) плюс (количество точек ниже прямой c = i и не левее прямой p = j умножить на j).

Будем двигать сканирующую прямую снизу вверх. Сначала рассматриваем c = 0, затем c = 1 и так далее. При этом для каждого p будем хранить величину d[p] — чему равен ответ на задачу при текущем c, если второй параметр будет равен p. Если у нас есть корректно посчитанный массив d[] и мы переходим от c к c + 1, как пересчитать этот массив для нового c?

Посмотрим на всех людей, для которых хоть что-то поменяется, очевидно — это люди у которых b[i] = c. При текущем c они еще пользовались бесплатной версией, но после увеличения на 1, они перестанут ей пользоваться. Понятно, что каждый такой человек i модифицирует массив следующим образом: d[1] +  = 1, d[2] +  = 2, ..., d[b[i]] +  = b[i].

Теперь можно переформулировать задачу в терминах структур данных. Есть два вида запросов: прибавить на префиксе возрастающую арифметическую прогрессию, узнать максимум среди всех элементов массива d. Один из способов решить такую задачу — корневая декомпозиция.

Разобьем все запросы на группы по sqrt(q) штук, в каждой группе выделим отрезки, на которых к ячейке d[i] значение i прибавляется с одним и тем же коэффициентом. Для каждого такого отрезка построим нижнее огибающее множество прямых y = d[i] + i·x. Так как запросов в группе sqrt(q), то и отрезков будет O(sqrt(q)). Значит прибавление на префиксе и взятие максимума можно будет делать за O(sqrt(q)).

Итоговая сложность решения: O(MAXX·sqrt(MAXX)), где MAXX — максимальное значение среди a[i] и b[i].

Разбор задач Zepto Code Rush 2014
  • Проголосовать: нравится
  • +117
  • Проголосовать: не нравится

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +7 Проголосовать: не нравится

Во второй задаче можно ещё заметить, что с любым конкретным пауком мы можем встретиться только в какой-то одной клетке. Если быть точным — с движущимися вниз мы не встретимся, с движущимися вверх встретимся в том же столбце, но только если они в четной строке. С движущимися влево и вправо мы можем встретиться только в столбцах с номерами j-i и j+i соответственно. (Все описанное — в нуль-индексации)

»
10 лет назад, # |
  Проголосовать: нравится -54 Проголосовать: не нравится

please hurry to write the report about other question.

»
10 лет назад, # |
  Проголосовать: нравится +30 Проголосовать: не нравится

Images in the problem statements were so good that I wish they (or similar ones) were present in the editorials too ;)

  • »
    »
    10 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +10 Проголосовать: не нравится

    Anudeep, Its very unfortunate that ur problem A failed otherwise you would have been in top 50.Hard luck,bro.:(

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится

      I have this habit of locking a solution as soon as i submit. I did the same with A. Then when I was implementing B (or C), I understood that my A will fail, quickly finished that problem and started hacking solutions with a case that my solution will fail. There were many others who did the same mistake, Got 7 hacks ;)

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I'm surprised that C can be solved by bruteforce :O

»
10 лет назад, # |
  Проголосовать: нравится +31 Проголосовать: не нравится

My solution for problem E:

Consider the levels with ascending a(i) and iterate through them. Let's say, we're now at level i, we have some decision to make here:

  • Choose 0 star here. It's easy to see that from now on, if we choose a 1-star level, let's call j, we have a(j)>a(i), which make swapping i and j lead to a better solution. So from now on we only choose 2-stars levels. Among all the remaining levels, we choose the ones with b(i) minimum to satisfy the required stars.

  • Choose 1 star here. Create a fake level with a=b(i)-a(i), b=+inf. Insert that fake level in our box.

To maintain the levels and take out the one with minimum a(i), we can use a heap (priority_queue) with two value a(i) and b(i).

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +2 Проголосовать: не нравится

    Awesome, coupled with noticing that you resolve the issue of adding the cost of all minimun b(i) with a Fenwick tree, I managed to get a working solution Thank you, have my like.

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Can someone show a short Java implementation of C using minimum spanning trees?

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Guys why the answer of the last example of 436D - Pudding Monsters is 1? Do we count the number of covered stars only when all the monsters combine in a single block? Can an optimal game finish before we combine them all?

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    We can stop the game at any time. Even if we did not make a single move. In the second example seconds and third monsters are already merged in one block and can not be separated.

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

with D can O(n*m) pass the systest? i thought the complexitiy is too large so used much time to think of wrong O(m^2 lg n) sol

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    Yes, time limit is 5 seconds bro.

  • »
    »
    10 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +7 Проголосовать: не нравится

    It is only 2·108. And operations are pretty simple. Integer addition and multiplication in straight-forward for-loops. My solution in C++ runs only 500 ms.

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится +8 Проголосовать: не нравится

      Here comes a line I'm often repeating: "Algorithmic problems are divided into two groups. Those were n log n TLEs for n<=10^6 and those were organizers say "It is only 2*10^8, today's computer do it in a 0,5s"" :P. Indeed in a very short period I experienced also my O(n log n) submission TLEing and my "favorite" organizer's excuse for ridiculously big constraints.

      • »
        »
        »
        »
        10 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        It is known, that there is always a constant multiplier behind big-O notation. One can not just ignore it. In this problem thr constant is small. In FFT algorithm, for example, it is bigger.

        In World Finals problem D had 25*25*10^6 ~ 6*10^8 solution that can or can not pass the tests depending on implementation. We experienced both options.

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I spent a few hours on Problem C to figure out how to find minimum spanning tree, so I decided to share what I've found out.

If you don't know how to find minimal spanning tree, this tutorial on YouTube will be really helpful.

I implemented my solution based on this editorial and the tutorial. I hope this helps if you are having trouble understanding/implementing!

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    can you explain me this : MST is O((n*M*k)^2) which will go out of time bound ?

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Kruskal's algorithm of minimum spanning tree runs in O(logE) time, and here maximum value of E is 10^3 * 10^3. Therefore, it will not exceed time limit. A better question to ask would be how building the graph would not exceed time limit-it takes around 10^8 operations, and while in here it does fit in time limit, I've seen other judges where it might've timed out.

»
10 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

Задача F. Что такое огибающее множество прямых,и в чем их смысл? И как находить ответ, имея это множество? Я знаю что такое sqrt-декомпозиция, но не очень понимаю как её сюда на эту задачу натянули) Может кто-нибудь поподробней объяснить? )

»
10 лет назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится

@Fefer_Ivan can you please provide the links to the solutions of the above problems(specially to the D and E)??

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Кто нибудь устроился в ZEPTOLAB? Как собеседование проходит? Какие вопросы задают? =))

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

По задаче Е.

Пользуясь вышесказанным, зафиксируем префикс L уровней в порядке сортировки по b[i]. Все уровни этого префикса мы должны хоть как-то пройти

Какие именно элементы с префикса L мы должны выбрать для прохождения на две звезды?

  • »
    »
    10 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    Берем все с префикса по 1 звезды. Затем кое-кого берем с префикса и переводим с 1 звезды на 2 ИЛИ берем кого-то НЕ с префикса на 1 звезду. Стоимость такой штуки для префикса = (b-a), для не префикса = a. Выбираем самые дешевые звездочки. Их кол-во (w-l)