Автор 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)

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

This comment is translated with Google translate, sorry for any spelling error, in the dungeons and candies problem it is specified that a level can only be loaded based on another if this level had been previously loaded, however in one of the tests in which my code is tested the example result does not follow this rule and compares 2 with 3, also it is only possible to get the given result as correct by skipping this rule