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

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

Всем доброго времени суток. Ребята, есть задачка: На плоскости задаются 2 множества точек — А и В, |A|=|B|=n. Пусть никакие 3 точки не коллинеарные. Нужно так сформировать пари (a, b), где a — точка из множества А, b — точка из множества B, чтобы никакие 2 отрезки не пересекались. Задача пересечения 2 отрезков всем известная, потому хотелось бы услышать идею именно на счет построения отрезков с такими условиями. Есть тривиальная идея полного перебора (в принципе, здесь бы подошел и бэктрекинг), но хотелось бы узнать, есть ли более оптимальные методы решения. Так же, если на каких-то архивах есть похожие задачки, то хотелось бы узнать их номера. Буду очень благодарен :))).

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

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

А что если соединить сперва как-ннибудь жадно, а потом пока есть пересечения перестраивать очевидным образом? Ясно, что процесс завершится ибо сумма длин каждый раз уменьшается.

Ясно, что работает не быстро, но все же вроде быстрее перебора наверно (По грубым оценкам — отрезков полином, точек пересечения полином => не более полинома раз что-то сделаем за какой-то опять же полином). А если еще соединить как-то хитро(например к каждой точке выбирать ближайшую свободную, или отсортить по 1 из координат и первую сединять с первой), то на практике должно быть быстрее.

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

    Могу ошибиться, Но задача напоминает (а может она и есть) Задачу со Всеукра. Либо прошлого, либо позапрошлого. Сводилась к построению выпуклой оболочки. На ней отрезки 100% не пересекаются. Отрезки брались, последовательные. А если две точки, стоящие рядом были из одного множества, соответственно не берем отрезок. Точки, отрезки которых мы взяли удаляем и переходим к шагу 1.

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

      Я думал о выпуклой оболочке, но на вопрос "Что если вся выпуклая одного цвета" ответа себе не нашел.

      PS: по понятным причинам всеукр не писал

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

        А я писал. Это был мой первый Всеукр. Я на ней тогда 25 баллов набрал. И еще на первой задаче (что-то типа найти сумму коэффициентов многочлена) на радостях от придуманного решения неправильно написал цикл вознесения числа в степень по модулю. О быстром тогда еще даже не знал, но навтыкал даже в линейном. Да... есть что вспомнить.

        P.S. Через 4 дня еду, как-раз таки, на свой третий, и, увы, последний Всеукр.

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

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

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

          А по какому принципу выбирать прямую?

          Могу ошибиться, но не всякая прямая гарантирует решение. Так ведь?

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

            Если в обеих частях будет поровну обоих цветов, то гарантирует вполне себе.

            Но непонятно, как это сделать, впрочем

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

              Ну пока все точки не обработаны: 1) ищем выпуклую оболочку 1.1) если на ней есть разные точки, то добавляем их (выводим там и т.п) и к п.1 1.2) если нет, то разбиваем пополам по цветам и передаем в рекурсию две части (или много памяти?)

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

                Почему можно разделить пополам?

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

                  Ну можно разделить примерно пополам (+-1 точка). Поскольку, нет 3х коллинеарных, то это возможно.

                  UPD: Хотя даже не очень принципиально, чтоб именно пополам. Главное, чтобы в каждом подмножестве было поровну точек. Опять же то, что нет троих коллинеарных, гарантирует (разве, нет?) то, что такое разбиение есть..

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

                  Если пытаться проводить только в 1 направлении — то нет

                  Пример(вертикальной тут нет, да и гориз. вроде тоже)

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

                  видимо если нет баланса 0, то есть переход от 1 к -1, можно порезать по нему, одну точку сюда, одну сюда.

                  Видимо поерил в такое решение

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

            Я вот сидел и думал над примером, когда, если разбивать тупо примерно пополам (да-да, по количеству цветов, пропустил), не будет решения. Увы, не нашел. Если кто найдёт, буду рад увидеть)

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

              Впрочем, ради научного интереса можно поискать архив с тестами (а заодно и разбор) и проверить. Вот только, боюсь, руки не дойдут. Еще много чего сделать нужно из запланированного =)

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

          Да, такое тоже кто-то писал.

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

N^2 log N точно решение есть. Каждый раз строим выпуклую оболочку и если 2 соседние точки разных цветов, то берем эту пару в ответ и удаляем из множества. Если выпуклая состоит только из точек одного цвета, то можно соединить одну точку из оболочки с одной из тех, что внутри ее, чтобы другие отрезки не пересекали этот. Как-то так.

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

    Привет коллегам из Александрии =)

    Примерно так оно и решается, я тогда в разбор не вникал =)

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

Так как автор вопроса из Украины, то думаю, что разбор с Всеукраинской олимпиады подойдет. Задача под номером 3. http://uoi2010.kmpu.edu.ua/day2.pdf

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

    Спасибо за найденный разбор, действительно, можно разделить вертикальной прямой =)

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

NEERC 2007-2008 (Problem A). Там n ≤ 100, можно решать, находя минимальное взвешенное паросочетание (вес — длина отрезка).

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

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

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

    Мне кажется, что такой метод "вращения прямой" поможет в том случае, когда нету условия неколлинеарности 3 точек, но заранее ведомо, что разбиение существует. Или я не совсем точно понял идею.

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

      Условие, что никакие три точки не лежат на одной прямой, существенно. Оно означает, что прямая, проходящая через 2 любые точки разбивает множество данных точек на 3 подмножества: первое – состоит из 2 точек, лежащих на этой прямой, второе и третье – точки, расположенные в полуплоскостях, граница которых – эта прямая. При этом второе или третье множество могут быть пустыми. Если добиться, чтобы первое множество состояло из разноцветных точек, а в первом количество точек каждого цвета было одинаковым, то в третьем эти количества также будут равны. При этом отрезки, соединяющие точки второго множества не будут пересекать отрезки, соединяющие точки третьего множества. Зафиксировав отрезок, соединяющий точки первого множества, мы получим ту же задачу для второго и третьего множеств, количество точек в которых меньше исходного. Повторяя разбиение для каждого нового множества в конце концов соединим требуемым образом все точки исходного множества.