Учитывая список целочисленных координат, найдите область самого большого выпуклого многоугольника, который вы можете построить из списка так, чтобы -
- каждая вершина находится в списке
- ни один элемент списка не содержится в многоугольнике.
Пример:
(0, 0) (8, 0) (0, 1) (3, 1) (7, 1) (1, 2) (5, 2) (9, 2) (2, 3) (5, 3) (7, 3) (3, 4) (5, 5) (11, 5)
Визуализация:
o o
o o o
o o o
o o o
o
o o
Самый большой выпуклый многоугольник, который вы можете сделать из этого:
o
o o
o o
o o
o
o
С площадью 12.
Вы можете взять список координат в любом разумном формате и вывести (соответствующим образом для вашего языка) область наибольшего выпуклого многоугольника, округленную до не менее 2 цифр после десятичной точки.
Кроме того, вы должны использовать какой-то алгоритм, а не просто перебор всех подмножеств точек. Чтобы обеспечить это, ваша программа должна решить список из 50 вершин за минуту на современном ПК.
Самый короткий код в байтах побеждает.
Ответы:
Javascript ES6, 738 байт
Вот версия ES5 или менее, которая должна работать в большинстве браузеров и узлов без подстройки: 827 байт
Код возвращает анонимную функцию. В качестве параметра он принимает массив точек, например
[[0,1],[2,3],[4,5]]
. Чтобы использовать его, вы можете поместитьvar f=
перед ним, или, если вы хотите использовать его из командной строки, добавить(process.argv[2].replace(/ /g,'').slice(1,-1).split(')(').map((x)=>x.split(',')))
в конец, и назвать его какnode convpol.js '(1,2)(3,4)(5,6)'
Спасибо за вызов! Так как эталонной реализации нет, я не могу доказать, что это правильно, но это согласуется, по крайней мере, для перестановок списка точек. Я почти не думал, что это сработает, поскольку версии с отладочным кодом, даже отключенным, были слишком медленными с экспоненциальным увеличением времени. В любом случае, я решил сыграть в гольф, и мне было приятно увидеть, что на моей машине он опустился до 2 секунд и набрал 50 очков. Он может рассчитать примерно 130 баллов за 1 минуту.
Алгоритм похож на сканирование Грэма , за исключением того, что он должен искать пустые выпуклые оболочки повсюду.
объяснение
Вот общий обзор того, как работает алгоритм. Суть этого алгоритма - просто поиск выпуклых петель против часовой стрелки, которые не заключают точку. Процедура примерно такая:
Кроме того, в качестве оптимизации мы записываем начальную пару цепочки как проверенную, поэтому любые поиски впоследствии при обнаружении этой пары в любом месте цепочки могут немедленно прекратить поиск, поскольку самый большой полигон с этой парой уже найден.
Этот алгоритм никогда не должен находить многоугольник дважды, и я экспериментально подтвердил это.
источник
===
и!==
на==
и!=
, но я не могу быть уверен, не понимая ваш код ...(x,i)=>p.i==i
(13 символов) немного дольше, чемx=>p===x
(8 символов) даже после оптимизации.