Блог пользователя ivan.popelyshev

Автор ivan.popelyshev, 16 лет назад, По-русски
В рамках проекта SnarkNews стартовала зимняя серия индивидуальных соревнований по программированию SnarkNews Winter Series - 2011. Серия состоит из 5 раундов. При этом каждый раунд проходит по правилам TCM/SE. Участвовать в серии могут те, кто или уже зарегистрирован на сервере личных соревнований SnarkNews (список зарегистрированных доступен по ссылке "Пользователи" в верхнем меню), или подал заявку на участие в SNWS-2011 согласно правилам серии по адресу sn_register(собака)snarknews(точка)info.
Участвовать в SNWS-2011 можно, начиная с любого раунда.

SN contests

NameTypeRegistration deadline
StartFinish
SNWS-11,R1 TCM/SE (1,1,4) -
01.01.2011 20:00 10.01.2011 14:30
SNWS-11,R2 TCM/SE (1,1,4) -
06.01.2011 14:00 12.01.2011 14:00
SNWS-11,R3 TCM/SE (1,1,4) -
12.01.2011 14:00 18.01.2011 14:00
SNWS-11,R4 TCM/SE (1,1,4) -
18.01.2011 14:00 24.01.2011 14:00
SNWS-11,R5 TCM/SE (1,1,4) -
24.01.2011 14:00 31.01.2011 18:00

Завершился первый раунд SnarkNews winter series-2011. Первое место занял Геннадий Короткевич (Беларусь, Гомель), второе - Пётр Митричев (Россия, Москва), третье - Дмитрий Джулгаков (Украина, НТУ "Харьковский ПИ").
При составлении первого тура были использованы задачи локальных контестов североамериканских университетов.

Прошу до конца раунда не обсуждать задачи в комментариях.
  • Проголосовать: нравится
  • +8
  • Проголосовать: не нравится

16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
При просмотре результатов из второго раунда и попытке перейти на "Summary after 2 rounds", выскакивает "Internal Server Error".
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Ааа, раньше просто промежуточные тоже вроде были :)
16 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +9 Проголосовать: не нравится
Знает ли кто-нибудь что такое WA14 в задаче B 1 тура? Он вроде уже закончился. Видимо я не совсем правильно понимаю что-такое невыгодная сумма. Может кто-нибудь дать формальное определение?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
объясните, пожалуйста, как можно зарегаться на сервере SnarkNews? я не нашел нигде кнопочку "регистрация" 
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Как решать D и F?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится
    В F надо уметь за O(1) получать значение в любой ячейке. Зная это и заметив, что значения на границе прямоугольника соответствуют унимодальной функции, можно искать минимум троичным поиском. Ну или если прямоугольник содержит начало координат, то ответ 0.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +6 Проголосовать: не нравится
    В D отсортируем все отрезки по возрастанию y координаты. Затем динамика
    f(i,l,r) - максимальная площадь многоугольника, построенного на отрезках 1..i в порядке сортировки, причем левая точка из отрезка l является верхней в левой цепи выпуклой оболочки, а правая точка из отрезка r является верхней в правой цепи выпуклой оболочки.

    Когда добавляем новую точку, пытаемся либо добавить ее к левой цепи (если она при этом не станет правее правой), либо к правой цепи, либо вообще не брать. При добавлении соответственно пересчитываем площадь многоугольника.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится -7 Проголосовать: не нравится
    За О(1) получаем значение в любой ячейке. Заметим что минимум прямоугольнике может находиться либо в (0,0) либо в одном из углов  либо на пересечении прямых |x+y| <=1 , |x-y|<=1 и периметра прямоугольника.
    Достатачно проверять только некоторые точки лежащие в прямоугольнике, я проверял все (a * x + b, c * y + d) где x, y это все возможные пары координат из (x1, x2, y1, y2) , |a|, |b|, |c|, |d| <  = 1.
16 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится
О, а объясните пожалуйста условие Е ("Переэкзаменовка") с первого раунда!
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +5 Проголосовать: не нравится
    Процент удачной сдачи теста равен 100 - (T - last) / 2 , T - время, в которое нужно сдавать этот тест, last - наибольшее время, которое <= T, когда происходила подготовка, и вот нужно эти подготовки оптимально расставить.
16 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +5 Проголосовать: не нравится
Fixed
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Расскажите, пожалуйста, как решать задачу A второго раунда.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    И задачу F если можно.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +1 Проголосовать: не нравится
      Задача F, если понимать ее в том толковании, в каком были составлены тесты, то есть что сеть можно развернуть 1 раз мгновенно и собрать всю рыбу, которая в нее попала, решалась следующим образом:
      Делаем двоичный поиск по радиусу. Для фиксированного радиуса для каждой рыбы определяем время входа и выхода в круг такого радиуса с центром в судне. Сортируем события входа и выхода рыбин из круга по времени и просто проходим список, считая, какое максимальное количество рыб может быть внутри круга в какой-то момент между событиями. Если это число не меньше того, которое нам надо - опускаем верхнюю границу поиска, иначе подымаем нижнюю.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Ну в задаче F понятно что нужно бинпоиск по радиусу. Теперь надо научиться проверять: существует ли такой момент времени когда в круге лежат хотя бы K рыб.
      Рассмотрим все рыбы, каждая рыба это луч. Рассмотрим лучи, которые пересекают круг. Они пересекают круг в течении какого-то отрезка времени. Теперь задача свелась к тому, есть ли точка, которая лежит хотя бы в K отрезках на прямой. Эта задача решается просто.
  • 16 лет назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится +14 Проголосовать: не нравится
    Решение по A

    Для начала решение на TL12. 

    Переберем все разности ai - bj. Найдем их gcd. Пусть оно равно некоторому g. Тогда почле четного шага мы можем получить только значения кратные g. Утверждается, что если есть как положительные так и отрицательные значения, то можно получить любое значение кратное g. Если нет то ответ, очевидно, NO. Теперь надо проверить для всех ненулевых остатков по модулю g есть такое значение в множестве А. В таком случае ответ YES. Иначе NO.

    Как это дооптимизить до OK.

    Ну заметим что после первой итерации цикла по A Поэтому если ai ≡ a0(modg) то цикл по b не нужен. Это гарантирует что gcd уменьшится, а значит число итераций порядка 30 () Итого 30 * 10000 * 500 = 1, 5 * 108 , что спокойно укладывается в 12 секунд. Тем более что оценка довольно грубая и на самом деле придется делать намного меньше чем 30 итераций.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Вопрос. Я понял условие задачи F следующим образом:
Сеть может быть развернута на любой промежуток времени / сколько угодно раз мгновенно. Я не нашел в условии противоречий этому, сдал, и получил ВА. Написал мыло на эту тему. Пока никакого эффекта. Может, я чего-то не заметил и условие действительно составлено так, что это толкование невозможно?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    Я тоже так сначала понял условие, но потом заметил предложение в конце Формата входных данных.
    • 16 лет назад, скрыть # ^ |
      ← Rev. 2  
      Проголосовать: нравится 0 Проголосовать: не нравится
      Если ты имеешь в виду фразу "в оптимальном случае", то  - в условии не сказано, что есть "оптимальный случай". Например, это можно понять как "если разворачивать сеть в такие моменты времени, что результат максимален".
      UPD: Пардон, это в конце формата выходных.
      В конце формата входных сказано, что можно использовать сеть в любой, даже не целый момент времени. Что по-прежнему ничего не говорит про возможное количество ее использований.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        нет, фразу: "Заметим, что траулер может использовать сеть в любой момент времени, начиная с времени 0.".
        • 16 лет назад, скрыть # ^ |
          ← Rev. 3  
          Проголосовать: нравится 0 Проголосовать: не нравится
          Да. И тут нигде не сказано, что он это может делать 1 раз.

          UPD:

          Да, если уж ругаться на условия)


          В задаче С в условии сказано, что k пробегает значения от 1 до m, а затем в формате входных данных - от 0 до m.


          В задаче D в тесте координаты даны не в формате (х,у), если считать нижний левый угол (0,0). Они отсчитывались сверху.


          В задаче E тест из условия содержит число 1020, хотя сказано, что максимум 1000. 


          Но все это не сильно повлияло на мой результат, в отличии от задачи Ф.
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится
            Я тоже когда в первый раз прочитал F подумал про такое толкование, но подумал что это слишком просто будет.
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится
            На счет жалоб по условиям - еще немного насторожила фраза в задаче A: "выясните, сможет ли курс на некоторый день стать в точности равным любому наперед заданному целому числу?". Получается, курс должен быть сразу равен всем целым числам :) Ну или хотя бы возможно такое неверное понимание "должен существовать такой день, что для любого целого X существует набор изменений курса, при котором в этот день курс станет равным X".
            Более корректно было бы "выясните, верно ли, что для любого целого X существует день, в который курс может равняться X".
16 лет назад, скрыть # |
 
Проголосовать: нравится -6 Проголосовать: не нравится
Немного смущает возможность сдачи задач в двух форматах ACM и TC. Сдаю задачи в формате ACM чтобы быть уверенным в правильности задач, теперь сожалею что не сдавал в формате TC все задачи третьего раунда прошли с первой попытки =(
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
http://158.250.33.215/~ejudge/tcm-se.html
тут сказано, что "При отправке решения "в открытую" участнику сообщается, зачтено решение или нет".
16 лет назад, скрыть # |
← Rev. 5  
Проголосовать: нравится +7 Проголосовать: не нравится
Never mind.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Третий раунд еще не закончился. "третий раунд продлён до 23:50 18.01.2011"
16 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится
А у всех сервер еле работает?
16 лет назад, скрыть # |
 
Проголосовать: нравится +13 Проголосовать: не нравится
эх, так хотел в тройку попасть, но продлили тур, и поучаствовал Саша Мангилёв, мои ему поздравления =)

коротко разбор 3-го раунда:

A. Очевидно, что если есть K сундуков длины Y, то мы их положим в K сундуков длины X > Y, а в них положим K сундуков длины Z < X. Конечно, не всегда мы их куда-то положим или что-то положим в них, но в любом случае, мы не можем их положить друг в друга. Они создают K комплектов. Значит, ответ - максимум из всех K.

B. Уберём из первой строки все символы ":" и ",", считаем в виде пар "строка-число" и поместим в мап. Пройдём по второй строке и будем извлекать кол-во дней для текущей экипировки из мапа. Лучше дописать в конец 2ой строки символ "|", видимо из-за этого некоторые участники и завалили задачу.

C. Заметим, что если есть числа A, B, C, D и A > B, C > D, то A * C + B * D > A * D + C * B. Сортируем столбцы с числами и выводим произведения в каждой полученной строке.

D. Построим граф следующего вида: N вершин - участники; если X может победить Y, то проведём ребро из X в Y. Пустим dfs из каждой вершины, которая принадлежит ордену. Когда мы в процессе поиска в глубину спускаемся из вершины I в вершину J, это означает, что мы поставим I и J в PvP и I победит J. Хронология событий слегка нарушается, но, при желании, её можно легко восстановить. Теперь посмотрим, все ли вершины оказались посещены? Если какая-то вершина не посещена, то это значит, что до неё нельзя дойти, чтобы победить.

E. Не знаю, почему описанное ниже решение верное, я просто порисовал на листике и не нашёл обломных случаев. Итак, пусть ярмарка происходит в некотором городе X, а не на цепи городов. Тогда дольше всего идти от самого дальнего города. Найдём пару самых дальних друг от друга городов A и B - их может быть несколько, это не проблема. Расстояние между ними Z. Расстояние от любого другого города до цепи A-B будет не больше, чем M  ≤  Z. Если возмём какую-нибудь другую цепь A-B (не самых дальних городов), то ответ может быть больше M. Отсюда решение: 3-мя (вроде можно и 2-мя?) поисками в глубину находим пару самых удалённых вершин друг от друга. Всю цепь отмечаем некоторым цветом. Потом от каждой вершины цепи находим расстояния до "неярмарочных" городов - максимум из них будет ответом.

F. По сути - игра "Сапёр". Я на туре понял условие так, что "количество способов поставить или не поставить бомбу возле клетки с цифрой не больше 105" и, поэтому, написал перебор. Думаю, что решать её нужно так: Рассмотрим каждую клетку с цифрой. Например, в ней написано C. Тогда получаем уравнение Ai + Aj + Ak + ... + Ax = C, где A? - это соседняя клетка, в которой, возможно, есть бомба. Составим такую систему уравнений. В условии гарантируется, что количество решений этой системы не превосходит 105. Следовательно, некоторые местоположения бомб придётся перебрать. Рассмотрим все решения системы и потом восстановим ответ.
  • 16 лет назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    По задаче Е я придумал следующиее док-во.

    Выберем две вершины А и B. Зафиксируем некоторую вершину С, ближайший к ней город с ярморкой обозначим К. Пусть w(A <-> K) <= w(K <-> B), если это не так, то можно просто "переназвать вершины".

    Утверждается, что существует такая вершина С, что w(A <-> K) < w(C <-> K), если путь A <-> B не является диаметром дерева. Действительно, если A <-> B не является диаметром дерева, то найдется такая вершина A' или B', что w(A' <-> B) > w(A <-> B) или w(A <-> B') > w(A <-> B) (обозначу это суждение *). Таким образом можно находить более весомый путь и повторять эти действия пока не достигнем максимума. Если же A <-> B диаметр дерева, то такой вершины С не существует, если бы она существовала, то можно было бы найти путь большего веса, чем А <-> B, а это противоречит определению диаметра графа.

    Вероность суждения (*) вытекает из корректности алгоритма поиска диаметра дерева.

    1) 1й поиск в глубину/ширину этого алгоритма служит для того, чтобы перейти в вершину являющуюся листом дерева. (можно превести аналогию с тем, что, если А и B -- не листья дерева, то всегда можно найти точку С, что K = A и очевидно, что после замены А на C w(A <-> B) увеличится.)

    2) 2й поиск в глубину предполагает, что мы его будем запускать из листа дерева и он найдет вершину, которая будет одним из концов радиуса дерева и к тому же будет самой удаленной от вершины из которой запускаем поиск. (Как это доказать я не знаю, просто поверим в это, ибо алгоритм работает). Соответственно если одна из вершин А B -- лист дерева (пусть это будет А), а другая не является концом одного из диаметров (пусть это будет B), то найдется вершина C (например, самая удаленная от А) и w(A <-> C) > w(A <-> B).

    3) 3й поиск ищет второй конец диаметра, этот случай очень похож на 2й.


    Любая критика приветствуется ;)


    • 16 лет назад, скрыть # ^ |
      ← Rev. 2  
      Проголосовать: нравится 0 Проголосовать: не нравится
      Диаметр находится 2-мя обходами. Берем любую вершину дерева и запускаем из нее обход с расчетом длины для каждой вершины. Теперь выберем среди всех вершин с максимальным расстоянием. Это один конец диаметра. Запустим второй обход с расчетом длины для каждой вершины. Самая удаленная вершина - другой конец диаметера. К вопросу нахождения листа - его можно найти без всяких обходов. Степень вершины равна 1 => лист. Так что в целом если убрать первый обход для нахождения листа, то получится как раз 2.
      Но на самом деле запускать можно и не из листа.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Думаю, что диаметр дерева можно найти одни дфс. Запускаем дфс из вершины где больше одного ребенка, выбираем два максимума по детям получаем цепь через текущую вершину претендующую на диаметр. Если ребенок один, то значит эта вершина уже учтена в другой цепи.
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Так можно найти диаметр, если запускать дфс из вершины, которая лежит где-то на диаметре. Произвольная вершина с более чем одним ребенком не пойдет.
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          n=11
          1 2
          2 3
          3 4
          4 5
          5 6
          6 7
          7 11
          2 10
          5 8
          8 9
          Диаметр 1->11. При запуске из 8 (2 сына) два максимума - это 1 и 10.
          • 16 лет назад, скрыть # ^ |
            ← Rev. 2  
            Проголосовать: нравится 0 Проголосовать: не нравится
            Чтобы было понятней, вот такой код:
                int len(int i, int p) {
                    int max = 0;
                    int max2 = 0;
                    int j = -1;
                    for (Link e : l[i]) {
                        if (e.i != p) {
                            int t = len(e.i, i) + e.c;
                            if (t > max) {
                                if (max > max2) {
                                    max2 = max;
                                    j = s[i];
                                }
                                max = t;
                                s[i] = e.i;
                            } else if (t > max2) {
                                max2 = t;
                                j = e.i;
                            }
                        }
                    }
                    if (j != -1 && max + max2 > best) {
                        best = max + max2;
                        x = i;
                        y = j;
                    }
                    return max;
                }

            UPD: в best - длина диаметра, в x, y - две вершины на цепи, по s[] можно восстановить всю цепь
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    А как в семпле задачи E получается 13? Не осилил...по идее должно быть 15..

  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    В задаче F осталась всего одна проблема. Рассмотреть все решения системы, где каждая переменная может быть либо 0, либо 1 :)
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +5 Проголосовать: не нравится
    В задаче D не обязательно строит граф. Достаточно при чтении проверить, есть ли хотя бы один не член ордена, который ни в одной паре не присутствует как "побеждаемый".
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +5 Проголосовать: не нравится
      Если такой есть, то все ясно, а если нет, то ничего не ясно.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Рыцари не могут побеждать друг друга одновременно. Если нет никого непобежденного, значит можно построить граф и запустить обход из рыцарей ордена и мы обойдем весь граф, потому что все рыцари не из ордена побеждаемые. Отсюда вывод, что утверждение выше - верное.