Привет, Хабр!

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

Текстовые задания

Дан самолет. На нем нет красный и нет синие точки и что на одной прямой нет трех точек. Покажите, что всегда можно соединить точки непересекающимися отрезками по два так, что каждая красная точка соединяется отрезком с синей, а каждая синяя точка соединяется отрезком с красной.

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

Совет по самоконтролю

Очевидно, что отрезки должны быть точно нет вещи.

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

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

Мое решение

Докажем по индукции. Базис представляет собой пустой набор точек. Идея перехода заключается в уменьшении размера проблемы нет проблемы с размером меньше n.

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

ЧИТАТЬ   Путин отправляет самолет в Вашингтон, округ Колумбия, чтобы забрать «ключевых дипломатов» через несколько дней после неудавшегося переворота Вагнера

Пример выпуклой оболочки для произвольного набора точек

Заметим, что если на границе полученного многоугольника хотя бы две точки имеют разный цвет, то рядом находятся две точки одного цвета. Найдем две такие точки, соединим их отрезком. Теперь все остальные точки находятся в одной из полуплоскостей относительно прямой, на которой находится наш отрезок, а значит, никакой другой возможный отрезок не будет его пересекать, т.е. можно «вычеркнуть» эту пару точек и перейти к проблема размера п-1.

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

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

Обратите внимание, что крайняя левая и крайняя правая точки принадлежат границе выпуклой оболочки, а значит, они одного цвета!

Движение прямой из левой точки вправо (прямая может быть не вертикальной)

Движение прямой из левой точки вправо (прямая может быть не вертикальной)

Мы посчитаем количество синих и красных точек слева от линии: red_cnt (х) И blue_cnt (х). Изначально red_cnt(x) = blue_cnt(x) = 0. Линия готовности пересекает первую синюю точку, затем red_cnt(x) = 0, blue_cnt(x) = 1. По мере движения строки вправо эти числа увеличиваются (каждый раз одно из чисел увеличивается на 1). В конце будет добавлена ​​последняя синяя точка и достигнутые числа n (cnt_red(x) = cnt_blue(x) = n). Это означает, что до того, как была добавлена ​​последняя синяя точка, значения были red_cnt(x) = n, blue_cnt(x) = n — 1. Те. у нас есть две функции, и blue_cnt начал расти раньше, но достиг нет позже чем red_cnt. Это означает, что эти функции принимают одно и то же значение где-то между левой и правой начальными точками: red_cnt(x) = blue_cnt(x). Другими словами, существует прямая, которая делит плоскость на две непустые полуплоскости, каждая из которых имеет равное количество синих и красных точек! Таким образом, мы уменьшили проблему размера нет две маленькие проблемы. ч.тд

ЧИТАТЬ   Что такое личная «средняя скорость» и как она влияет на нашу жизнь - Лайфхакер

Решение авторов проблемы

давайте строить нет отрезки, концы которых соединяют точки разных цветов (не обязательно без пересечений). Можно построить так: пока есть точки, не соединенные отрезком, возьмем пару «свободных» точек и соединим их.

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

Переход от пересечения пары отрезков с уменьшением общей длины

Переход от пересечения пары отрезков с уменьшением общей длины

Заключение

Особенность второго решения в том, что мы ввели некий числовой параметр, характеризующий построение, и научились выполнять действия, приводящие к его уменьшению. Лично мне это напомнило задачу на двадцать карт из моего любимого фильма. Х+Г (см. выдержку на английском языке.), так отозвался в моей душе. Впрочем, если бы я сразу подсмотрел его, я бы никогда не придумал свой.

СПАСИБО

Спасибо авторам Успешно пройти следующее собеседование по программированиюблагодаря которому я узнал об этой проблеме.

Спасибо также Виктору Криштаповичу и Артему Грачеву, которые выслушали мой поток сознания.

Source

От admin