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

Автор Egor, 13 лет назад, По-русски

Не забудьте, всего через пол часа, в 18:00 по Москве начнется второй раунд GCJ

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

»
13 лет назад, скрыть # |
 
Проголосовать: нравится -21 Проголосовать: не нравится

Зачем минусуете? Здесь же можно будет обсудить задачи после контеста!

»
13 лет назад, скрыть # |
 
Проголосовать: нравится -6 Проголосовать: не нравится

Спасибо огромное за этот пост!

Без иронии, я умудрился забыть про контест.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
»
13 лет назад, скрыть # |
 
Проголосовать: нравится +49 Проголосовать: не нравится

Не плохой такой у bmerry last second save :)

»
13 лет назад, скрыть # |
 
Проголосовать: нравится -21 Проголосовать: не нравится

Сколько человек дальше идут? Сколько футболки получают?

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Как решать A и C?

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

    На А можно было сортонуть все рейсы, потом идти слева на право, хранить сколько человек должны выйти на каждой станции, и сколько есть каждых карточек. Когда нужно кому-то выходить, то жадно отдаем самые новые карточки.

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

    Разбор доступен сразу после контеста в dashboard.

  • »
    »
    13 лет назад, скрыть # ^ |
     
    Проголосовать: нравится -21 Проголосовать: не нравится

    В A — тупая жадность.

    Для начала посчитаем сколько будет потрачено, если никто не будет меняться карточками. Это делается тривиально, если использовать формулу суммы арифметической прогрессии.

    Теперь найдем, сколько потратить можно, если оптимально передавать карточки. Заведем массив событий, в котором будем хранить для каждой станции метро (из тех, что есть во входных данных) сколько человек заходят и выходят на этой станции. Всего таких событий будет не более 2·M. Дальше будем идти по событиям. Когда люди где-то выходят, то им выгодно выйти с карточкой, которая в пути как можно меньше времени из тех, что еще не сданы при выходе. То есть надо использовать карточки, которые были взяты при входе на как можно более поздних станциях. Ну, а как обрабатывать добавление карточек — зависит от реализации.

    Реализовать это можно на обычной бинарной куче (priority_queue в C++).

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

    В задаче С надо было записать в граф все ограничения, которые мы имеем из массивов A и B, а именно:
    В массиве A:
    1. если i < j, A[i] >= A[j], то X[i] > X[j].
    2. для каждого A[i] != 1, X[i] больше, чем X[j], где j — номер последнего A[j] == A[i] — 1.

    Аналогично для массива B. потом просто осуществить топологическую сортировку в этом графе, при этом, понятное дело, из двух несравнимых вершин раньше идёт та, у которой меньше номер (чтобы последовательность получилась лексикографически минимальной).

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

      при этом, понятное дело, из двух несравнимых вершин раньше идёт та, у которой меньше номер

      Какая будет сортировка для графа из трех вершин с одним ребром 3->1?

      Нам ведь надо лексикографически минимальную обратную к топологической сортировке перестановку

      • »
        »
        »
        »
        13 лет назад, скрыть # ^ |
        ← Rev. 2  
        Проголосовать: нравится -8 Проголосовать: не нравится

        2 3 1
        не, я имел в виду, что ребро идёт из i в j, если мы точно знаем, что x[j] > x[i].

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

          Но сортировка 2 3 1 даст значения x = {3, 1, 2}, что больше, чем {2, 3, 1}

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

            Ты прав.
            На самом деле я делал так: перебирая числа от 1 до n, которые мы запишем массив, каждый раз выбирал самое раннее место, куда его можно поставить.

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

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

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

                Достаточно было посмотреть scoreboard и убедиться, что у меня зашло, или ты не веришь в квалифицированность организаторов GCJ?
                Очевидно, что при таком подходе на первом месте окажется самое маленькое возможное число.

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

                Мне вот пока не удается понять почему это правильно. Я сдал такую же лажу в контесте, но потом понял, что можно нормально лексмин искать, но было уже поздно :)

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

            Вообще есть и не рекурсивный алгоритм топологической сортировки. Он заключается в следующем: Выбирать любую вершину, из которой ничего не выходит. Добавить её в сортировку. Удалить из графа вместе со всеми рёбрами. Повторить. Этот алгоритм вполне подходит для того, чтобы находить лексмин топосрт

»
13 лет назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Решение, которое я сдал по С. Кто-нибудь умеет доказывать? Вообще без понятия, почему работает, и еще больше без понятия, почему lex-min.

Будем ставить числа по возрастанию. Когда мы поставили какой-то набор чисел есть оценки снизу на ai, bi. Поставим очередное число в самую левую, в которой оценка уже достигла того, чего надо, и если поставить туда нигде оценка не превысит ограничения. Код. Он видимо понятнее чем описание.

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

    Построение хоть какого-то легко доказать (мы каждый раз ничего из "пула" возможных не выкидываем, только добавляем)

    Насчет лексикографической минимальности умею убедительно махать руками :)

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

      А я кажется наоборот умею доказывать лекс. мин в предположении того, что ты сказал (именно твоего утверждения, а не построения хоть какого-то). Но не умею доказывать, что по второму условию ничего не может выкинуться.

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

        Ровно потому, что "нигде оценка не превысит ограничения". У нас плохо то может стать только от того, что стало слишком много

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

          Нет, смотри. Почему из-за того, что мы сделали A, мы не перестанем мочь B, потому что оно начнет мешать С, а раньше не мешало?

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

            А как оно может начать мешать С? Если С правее, чем В, то оно может начать мешать, только если А увеличил путь для В, а он не мог

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

Посмотрел я на список людей с 37 очками, и понял что не один я недоволен тем что C-small < A-large...

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +2 Проголосовать: не нравится

Одного меня удивило, что ровно на 500-м месте находится чемпион Мира по программированию?

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Можно для нубов идею по Б?

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

    Если не смотреть в Dashboard'е разбор, то бинарим по ответу и жадно моделируем за количество раундов. Для деталей реализации просто посмотри чужие решения.

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

    Научимся для каждой команды находить, какое максимальное место она может занять. Это означает, что эта команда сначала выигрывает все, что только может, а потом начинает проигрывать. Что означает, что команда выигрывает? Это означает, что среди тех команд, которые до сих пор выступали так же, как она, есть команда, с меньшим номером.

    Оk, храним 4 значения: количество команд, которые на сей момент выступили лучше данной количество команд, которые на сей момент выступили хуже данной (с этими командами рассматриваемая команда не поменяется местами уже никогда). количество команд, которые на сей момент выступили так же, как данная, но их номер меньше (они сильнее) количество команд, которые на сей момент выступили хуже данной, но их номер больше (они слабее)

    Первоначально эти значения равны 0, 0, k, N — k — 1 (где k — номер рассматриваемой команды)

    Дальше прогоняем N раундов. Чтобы подняться как можно выше, команда должна выиграть очередной раунд. Она может это сделать, если последнее значение больше 0. Также желательно, чтобы как можно больше БОЛЕЕ СЛАБЫХ команд, чем рассматриваемая, выступили так же, как она (чтобы потом можно было выигрывать у этих команд). Значит, слабые команды играют друг с другом и выигрывают друг у друга, поэтому последняя величина сокращается в два раза, а проигравшие перемещаются вниз. Аналогично, команды, которые выступили так же, как текущая, но сильнее ее играют друг с другом, проигравшие спускаются вниз.

    В итоге получаем лучшее место, которое может занять команда номер k. Похожим образом определяется худшее место, которое может занять команда номер k. Дальше перебираем все команды и для каждой определяем наихудшее и наилучшее место — вот и ответ. Для решения B-large нужно перебор заменить на двоичный поиск по ответу.

    • »
      »
      »
      13 лет назад, скрыть # ^ |
      ← Rev. 2  
      Проголосовать: нравится -9 Проголосовать: не нравится

      Вот мой код: http://pastebin.com/4vKtwdWG

      Думаю, что он вполне понятный.

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

        http://pastebin.com/z6iLRNcd

        Какой-то у тебя длинный подсчет позиции в лучшем и худшем случае.

        • »
          »
          »
          »
          »
          13 лет назад, скрыть # ^ |
           
          Проголосовать: нравится -9 Проголосовать: не нравится

          Длинное то, что внутри цикла? Может быть, это можно сократить, я не придумал. Еще я отдельно разбирал случай, когда сверху-снизу остается четное и нечетное число команд — конечно, это можно сделать одной формулой, но я для надежности написал if

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

          А, ну у тебя рекурсия вместо цикла — я это не представлял себе рекурсивно. Рекурсия короче записывается, да.

          Плюс с четностью-нечестностью я поосторожничал.

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

      весь контест смотрел на ~(p-1), вроде как маска игр последнего призера, а для участников пытался составить лучшую и худшую маску, но не смог понять принцип построения. Видимо только моделирование.. Спасибо.

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

      А почему Вы считаете, что команда должна выигрывать все, что может. Может быть, она поочередно то выигр., то проигр.?

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

        потому что если она выиграет после какой-то череды поражений, то ничего не мешало выиграть у той же самой команды до случившихся поражений и обеспечить себе нужное место раньше

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

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

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

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

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

        Место команды определяется лексикографическим порядком строки из побед и поражений этой команды, поэтому для того, чтобы занять как можно более высокое место нужно выигрывать, если это возможно.

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

    Решение за O(1) на тест: http://pastebin.com/aufkpZjV

    Использует встроенную в GCC функцию __builtin_clzll, которая (как минимум) на x86 выполняется за константное время. В остальном идеальный C99.

    (Решение придумал сам и только сейчас сравнил с официальным. То же самое, хотя в официальном есть недочёт, из-за которого при P = 2N оно первым числом выводит несуществующий номер команды 2N + 1 - 2 вместо 2N - 1. Замечу, что во время контеста я отправил более медленную версию, работающую за O(N), — это я уже поотимизировал.)

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +4 Проголосовать: не нравится