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

Автор natalia, 13 лет назад, перевод, По-русски
Задача A

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

Задача C

Сначала посчитаем, сколько в последовательности хомячков.  Пусть их h. Переберем позицию, в которой будет начинаться последовательность хомячков, и для каждой начальной позиции посчитаем, сколько тигров оказалось в отрезке h, начиная с этой позиции.  Этих тигров придется поменять с хомячками за количество обменов, равное количеству тигров, стоящих не на своем месте. Выберем минимум по всем начальным позициям.

Задача F

Во-первых, заметим, что все описанные операции (открытие/закрытие дверей, перемещения из одной комнаты в другую, обмен ключами) обратимы. Поэтому можно применить несколько таких операций из начального расположения и получить некоторое расположение A, и затем получить то же расположение А путем применения подобных операций из конечного расположения, в этом случае ответ будет "YES". Применим следующую стратегию к обоим расположениям: пока существует человек, который может перейти в некоторую комнату и открыть некоторую дверь, выполнять это действие. В результате для каждого из расположений мы получим связные подмножества комнат (будем называть из связными частями дома), соответствующие подмножества людей и ключей в каждой связной части дома. Если результирующие подмножества совпадают для начального и конечного расположения, то ответ на задачу "YES", иначе ответ "NO". Действительно, в случае совпадения можно очевидным образом из начального расположения получить результирующее, а из него - конечное. В противном случае это невозможно сделать, потому что найдутся ключи, которые не могут быть применены к соответствующим дверям, находящимся в другой связной части дома,  или найдутся люди, которые не имеют возможности проникнуть в комнаты, расположенные в другой связной части дома.

Во-вторых, несколько слов о реализации. Один из возможных способов - хранить две булевы матрицы
1) определяющую для каждого человека, может ли он попасть в каждую из комнат, и
2) определяющую то же самое для каждого ключа,
и рекурсивно выполнять операции:
1) если человек может оказаться в комнате, попробовать сделать переходы в соседние комнаты,
2) то же самое для ключей, пытаясь при этом открывать дверь в соседнюю комнату,
3) когда дверь открывается, сделать переход для людей и ключей в смежных комнатах.

Таким образом, мы перебираем каждую пару человек-комната, человек-дверь, дверь-ключ, дверь комната O(1) раз, поэтому общая асимптотика решения O(nk + km + m2 + nm).    

Задача G

Заметим, что длинами сторон могут быть числа , , , и т.д., т.е. корни целых чисел, представимых в виде a2 + b2. Сгенерируем достаточное количество таких чисел. Обозначим их , , ... В некоторых случаях можно взять в качестве длин сторон первые n чисел, но в некоторых случаях этого сделать точно нельзя. Все зависит от четности. Если сумма r1 + r2 + ... + rn нечетна, это невозможно сделать. В самом деле, каждую сторону можно представить вектором  (xi, yi), xi2 + yi2 = ri (xi и yi могут быть отрицательными).  Если число ri четно, сумма xi + yi также четна. Если ri нечетно, то и xi + yi нечетно. Если можно построить многоугольник с векторами сторон (xi, yi), то x1 + x2 + ... + xn = 0 и y1 + y2 + ... + yn = 0, поэтому общая сумма x1 + ... + xn + y1 + ... + yn должна быть четной! Но если сумма r1 + ... + rn нечетна, она также нечетна, и построить многоугольник невозможно.

Возьмем числа r1, ..., rn, если их сумма четна, иначе возьмем r1, ..., rn + 1 и выбросим одно из них, чтобы сделать сумму четной (в своем решении я выбрасываю наибольшее из таких чисел). Для каждого ri выберем неотрицательные xi и yi, xi2 + yi2 = ri. В общем случае существует 8 возможных ориентаций вектора (xi, yi), ( - xi, yi), (xi,  - yi)( - xi,  - yi), (yi, xi), ( - yi, xi), (yi,  - xi)( - yi,  - xi). Решим следующую подзадачу - заориентировать векторы таким образом, чтобы их сумма равнялась нулю. Это можно сделать при помощи следующего жадного алгоритма. Будем перебирать векторы, начиная с наибольших по длине. Будем вычислять текущую векторную сумму, которая изначально равна (0, 0) и будет пересчитываться при каждом добавлении вектора. На каждом шаге будем выбирать ориентацию, минимизирующую текущую сумму (по длине) при добавлении к ней. Затем, когда векторы заориентированы, отсортируем их по полярному углу и, прибавляя их последовательно, получим выпуклый многоугольник. Описанный алгоритм находит требуемый многоугольник на всех возможных тестах.

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

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Уже не впервые вижу тот факт, что такая задача "замыкания" ломаной из векторов решается жадностью. Нельзя ли каким-то образом объяснить, почему она решается жадностью, при чем именно такой, с проходом в порядке убывания длин, при чем всегда хватит не более чем первых Н+1 самых коротких векторов? Как я выяснил, проходит решение и если минимизировать расстояние от текущей вершины ломаной до (0,0) , и сумму модулей координат.
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +10 Проголосовать: не нравится
    Рассмотрим для простоты случай, когда берутся первые n длин (сумма четная). По индукции можно показать, что текущая сумма в нашем алгоритме по длине не превосходит последний прибавленный вектор. Действительно, после первого шага она в точности равна ему. Пусть перед очередным шагом мы имеем сумму (x, y) (будем без ограничения общности предполагать, что x и y неотрицательные, x ≤ y) и сейчас мы хотим прибавить вектор (a, b) (a, b тоже неотрицательные, a ≤ b). Нужно доказать, что (x - a)2 + (y - b)2 ≤ a2 + b2. Причем по предыдущим шагам индукции нам известно, что  x2 + y2 меньше всех возведенных в квадрат длин больших векторов, в частности, x2 + y2 ≤ (a + 1)2 + b2
    Итак, нужно найти максимум функции f(x, y) = x2 - 2ax + y2 - 2by в области x, y ≥ 0, x ≤ y, x2 + y2 ≤ (a + 1)2 + b2. Его можно найти и установить, что он равен нулю, т.е. требуемое неравенство выполняется.
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
    Вообще, это может оказаться полезным в каких нибудь других задачах, можно показать, что, если у нас есть 2 вектора v1(x1, y1), |v1| = L1 и v2(x2, y2), |v2| = L2, то если мы выбираем ориентацию одного из них так, чтобы длина вектора v1 + v2 *  была минимальна, то |v1 + v2 * | ≤ |L1 - L2|. Из этого факта, в частности в этой задаче, следует тот факт, который доказала Наташа.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Неправильный факт. Например, v1 = (3, 1) и v2 = (1, 1). Выбираем ориентацию v2, получаем сумму (2, 0). Ее длина равна 2, в то время как .
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Более того, справедливо противоположное неравенство |v1 + v2 * | ≥ |L1 - L2|. Это неравенство треугольника. Причем оно выполняется в любой метрике: и в евклидовой, и в манхэттэнской.   
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Упс, и правда ошибочка вышла.... Сорри. Спасибо Наташ, что поправила.
13 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится
:)

Though the checker was wrong, I favour problem G.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
faint, I can't see the pictures...
13 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится
i dont understand, why sum of first n, or n of first n+1 will yield (0,0) sum.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Можно, пожалуйста, тест 6 по задаче F?
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Почему "отказ тестирования" по G?
13 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится
For G, how to justify that the greedy algorithm is correct?