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

Автор Ripatti, 13 лет назад, По-русски
A. Нужно было просто сделать то, что написано в условии. Единственный подводный камень в данной задаче - лидер может иметь отрицательное количество очков.

B. В данной задаче предполагается придумать оптимальную стратегию "зайцу", а затем просто симулировать игру.

Выигрышная стратегия для "зайца" - держаться от контролера подальше. А именно - в минуту движения поезда нужно отходить от него, если это возможно. В минуту остановки нужно переходить в вагон, до которого контролер доберется позже всего. Это всегда либо первый либо последний вагон поезда.

Так же можно было написать простенькое дп или классическую игру.

C. Назовем траекторией линию, которую описывает центр бильярдного шара во время своего движения. В начале своего движения шар выбирает одну из не более чем двух траекторий и движется по ней. Пусть общее количество траекторий равно k. Обозначит также максимальное количество попарно не бьющих друг друга шаров (ответ для нашей задачи) как z.

Теорема. z = k.
Доказательство. Каждый шар покрывает как минимум одну траекторию, а два различных шара не могут покрывать одну и ту же траекторию, иначе они будут бить друг друга. Значит z ≤ k.
Теперь покажем, как расставить k шаров так, чтобы они не били друг друга. Каждая клетка периметра принадлежит ровно одной траектории, а каждая траектория покрывает хотя бы одну клетку периметра. Значит, существуют k клеток на периметре, принадлежащие различным траекториям. Именно в них мы и поместим бильярдные шары. Конец доказательства.

Теорема дает конструктивный способ нахождения числа k --- для этого нужно просто посчитать количество компонент связности в графе, изображенном на картинке ниже. Это можно сделать с помощью BFS, DFS или системы непересекающихся множеств за время O(n + m).


Например, на картинке 4 компоненты связности.

В данной задаче также есть решение в виде формулы: z = gcd(n - 1, m - 1) + 1. Можно было написать тупое решение и заметить эту формулу. Однако, доказать корректность такого решения несколько сложнее.

D. Заведем структуру данных, которая поддерживает быстрые операции добавления, поиска, извлечения любого элемента и поиска минимального элемента. Для этого, например, подойдет std::set в C++ или аналогичный контейнер в других языках. В этой структуре данных будем хранить отрезки пустых крючков так, чтобы извлечение минимума давало тот отрезок, в который нужно повесить пальто текущего сотрудника. Кроме того, для каждого сотрудника будем хранить отрезки пустых крючков, которые находятся непосредственно левее и правее.

С помощью этих структур можно за время проэмулировать работу раздевалки. Сложности начинаются с ответами на запросы директора. Нужно как то быстро втавлять элементы в массив, удалять и отвечать на запрос суммы на отрезке.

Онлайн решение. Для такого решения можно было написать какое нибудь балансированное или декартовое дерево.

Оффлайн решение. Сначала пройдемся по всем запросам из входа "в холостую" (то есть не отвечая на запросы директора) и сохраним все координаты, куда мы когда либо вешали пальто. Затем сожмем координаты и пройдемся по запросам второй раз. Теперь для подсчета сумм на отрезке можно использовать, например, дерево Фенвика.

E. Следующий набор команд позволяет поменять местами фишки на позициях 0 и 1: D1 R1 D1 L1 D1 R1 D1 L1 D1 R1 D1 L1 D1. Этот набор команд можно было найти либо на бумаге, либо используя двунаправленный BFS с ограничением количества допустимых ходов (на самом деле можно обойтись обычным BFS, если допустимые ходы ограничить очень сильно). Аналогичным образом можно менять местами любые две соседние фишки.

Теперь мы умеем менять местами два соседних элемента за 13 базовых операций. Дальнейшее решение строится тривиально и легко укладывается в ограничение в 10000 ходов.
Разбор задач Codeforces Beta Round 68
  • Проголосовать: нравится
  • +43
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
В D когда прочитал, возникла точно такая же идея решения (Оффлайн). Но к сожалению, прочитал я эту задачу за 3 минуты до конца :(
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
sf!

The problems are good
  • 13 лет назад, # ^ |
      Проголосовать: нравится -21 Проголосовать: не нравится
    请问如何证明那条公式呢?
    • 3 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      In this problem alse some solution by formula exists. z = gcd(n - 1, m - 1) + 1. You may wrote some stupid solution for observe it. But this formula is difficult for prove.

      或许是出题人证不出来 :P

13 лет назад, # |
  Проголосовать: нравится -20 Проголосовать: не нравится
Блин... Почему я не стал думать насчет gcd? Фак...
13 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится
Оффлайн-решение можно превратить в онлайн, если не сжимать координаты, но тогда вместо дерева Фенвика нужно использовать дерево отрезков с динамическим построением.
  • 13 лет назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится
    это что еще за структура такая? где можно почитать?
    • 13 лет назад, # ^ |
        Проголосовать: нравится +11 Проголосовать: не нравится

      Видимо имеется в виду дерево отрезков, построенное как бы над массивом из 109 клеток. Явно все дерево не создается, хранятся только интересные вершины, в подотрезке которых что-то было или есть. А в указателях на все остальные вершины просто записан NULL.

      • 13 лет назад, # ^ |
        Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится
        Осознал. И даже понял почему это работает))

        UPD. Аналогичным образом понял почему работает дерево Фенвика на мапе.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Да, именно это я имел ввиду.
13 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится
Can anybody prove the formula solution in problem C?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится
    Dmitry.Gerasimov: I spent some time doing that (would clearly have gotten me out of the competition :). Here's an outline:

    Create a 2(m-1) x 2(n-1) board and consider the point (i,j) to be the same as ( 2(m-1) - i, j ), ( i, 2(n-1)-j ), and ( 2(m-1) - i, 2(n-1) - j).

    (so e.g. (m-1, n-1) is the same as itself, and that's also how it should be :)
    This is a standard trick, I believe.

    Now a trajectory can be represented by a path in the big board; each point on the straight line will be equivalent to a correct one (belonging to the bouncy trajectory). The new board should be considered a torus.

    Forget the old board and count how many points in the top row (and bottom row, but that's the same) of the new board you reach by starting in (0,0). Finally check which ones you counted twice to get the answer for the old board. This uses the easier result that the number of points of a trajectory on a M x N-board. In fact, the points are {(i,j) : gcd(M,N) divides (i-j) [which is well-defined]}.
13 лет назад, # |
  Проголосовать: нравится +11 Проголосовать: не нравится
Кстати, в задаче С еще верна следующая формула: (n*m)/(v)+((m*n)%v?1:0), где v - количество уникальных ячеек, пройденных шаром, запущенным из любого угла. Как это доказать тоже вообще неясно, как и то, какая тут связь с формулой с гцд, хотя она, естественно, должна быть :)
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Похожая задача есть на тимусе: 1762. Она тоже решается одной формулой и тоже через НОД.
13 лет назад, # |
  Проголосовать: нравится +14 Проголосовать: не нравится
For problem C:

In an nxn board , a ball starting from any point on a boundary comes backs to the same point without touching any other ball on the same boundary.

So , it's clear that nxn board is equivalent to nx1 board(for placing the balls) , in which case answer is n.

let a and b be the sides of board,

So if a > b keep on shrinking bxb blocks to bx1 block.

Code:
while( a > 1 && b > 1 ){
                if( a > b)  a = a - (b - 1);
                else          b = b - (a - 1);

return a + b - 1;
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    It's totally the same as gcd (n-1, m-1)+1, I'm sure
    If it's the proof of this formula, please tell, why we can say that "So if a > b keep on shrinking bxb blocks to bx1 block."
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      We can get optimal number of balls by placing them only at boundary of one of the two smaller sides. Reason being , any point on any other boundary can be reached by some point from "the boundary" said above.

      Say , in a x b grid with a > b "the boundary" is the left wall i.e 1st column.

      Now trace the path of a ball travelling from from a point at "the boundary" back to some point on "the boundary". You will observe that ball goes and comes back from the same point at  (a - b + 1)th column.

      Hence , for tracing the paths in order to find conflicting points at "the boundary" we don't  require columns farther that (a - b + 1)th column.

      This is why we can say a = a - b + 1;
  • 4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Great Work, absolutely correct! The key point in "reducing the size" was due to the "unchanged positional behaviour" of boundary of (txt) matrix as mentioned above, which is easily provable.

    Moreover, a better/general visualization of the problem can be to tessellate the board in R2.

13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
Извел три листа бумаги на Е... В итоге решил так:
R2 D2 L2 U2 - переставить числа по треугольничку, причем из позиции 2,2 число поднимается наверх. Этого уже достаточно чтобы выстроить все кроме последнего ряда.
Дальше можно такими треугольничками и сдвиганием верхнего ряда переставить 1 2 3 в 3 1 2. Две таких перестановки и как раз получается обмен соседних клеток.
13 лет назад, # |
Rev. 2   Проголосовать: нравится +1 Проголосовать: не нравится
задача С убила :)))
P.S. сдал ее с помощью gcd конечно :)))