Вам предоставляется список ( a, b ) и список x . Вычислить максимальный топор + б для каждого х . Можно предположить, что a , b и x являются неотрицательными целыми числами.
Ваша программа или функция должны выполняться в ожидаемом (случайном порядке, если ваш код включает это, а не во вводе) O ( n log n ) время, где n - общая длина ввода (сумма или максимум длин обоих списков).
Это код-гольф. Самый короткий код выигрывает.
пример
[[2 8] [4 0] [2 1] [1 10] [3 3] [0 4]] [1 2 3 4 5]
Выход:
[11 12 14 16 20]
Объяснение:
11 = 1*1 + 10
12 = 1*2 + 10 = 2*2 + 8
14 = 2*3 + 8
16 = 2*4 + 8 = 4*4 + 0
20 = 4*5 + 0
Примечание о сложности:
Если вы использовали встроенную систему, имеющую хорошую сложность в среднем случае, и ее можно рандомизировать, чтобы легко получить ожидаемую сложность в теории, вы можете предположить, что ваш язык сделал это.
Это означает, что если ваша программа может быть проверена на O ( n log n ), возможно, с исключениями в крайнем случае из-за реализации вашего языка, но не может быть логически видна в вашем собственном коде, мы скажем, что это O ( n log n ).
источник
O(n log(n))
? Можете ли вы предоставить эталонный алгоритм?Ответы:
Pyth -
9998 байтЭто в значительной степени прямой перевод ответа @ KeithRandall's Python. Это определенно может быть гораздо больше.
Я скоро опубликую объяснение.Принимает два списка через запятую, разделенных запятыми через стандартный ввод.
Попробуй здесь
источник
Python, 214 байтов
Вычисляет выпуклую оболочку путем перебора входных данных
a,b
в возрастающемa
порядке. Выпуклая оболочка записывается вH
формате-1,0,x1,a1,b1,x2,a2,b2,x2,...,xn,an,bn
гдеxi
координата x пересеченияa{i-1},b{i-1}
иai,bi
.Затем я перебираю входные данные
x
в отсортированном порядке, обрезая выпуклую оболочку, чтобы идти в ногу со временем.Все линейно, кроме сортов O (n lgn).
Запустите это как:
источник
H
линейно для каждогоx
дюймаX
, не так ли ?. Разве не возможно, что у нас сложность O (n ^ 2), когда оба списка имеют одинаковую длину?H
линейно для каждогоx
, но потому что я делаюx
s для того, чтобы я запомнил, где остановился последний поиск, и начал следующий поиск там. Таким образом, внутреннийwhile
цикл может выполняться не более O (n) раз во всехx
(даже если он может выполнить O (n) раз для любого человекаx
).while
циклом в первомfor
цикле.Haskell, 204
271байтРедактирование : значительно улучшило игру, обновив выпуклый корпус в виде списка (но с той же сложностью, что и в версии без гольфа), используя «split (x + 1)» вместо «splitLookup x» и удалив все квалифицированные вызовы функций, такие как Predule. foldl.
Это создает функцию f, которая ожидает список пар (a, b) и список значений x. Я думаю, что все члены семейства APL сдувают его по длине, используя те же идеи, но здесь это так:
Пример использования:
Работает за O (n log n) времени; см. ниже для анализа.
Редактировать: вот версия без гольфа с анализом big-O и описанием того, как все это работает:
источник
Common Lisp - 648
692С реальным бинарным поиском.
объяснение
Пусть n - длина (a, b), а k - длина точек.
a
(параллельные линии), сохраняя только параллельную линию с максимумомb
, который всегда больше другого (мы предотвращаем деление на ноль при вычислении пересечений) - O (n)исходя из этого списка, создайте лямбду, которая выполняет интервальную проверку своего ввода и вычисляет максимальное значение - двоичное дерево построено в O (n) (см. /programming//a/4309901/124319 ). Применяемый двоичный поиск имеет сложность O (ln (n)) . На примере ввода мы строим следующую функцию (эта функция затем компилируется):
применить эту функцию для всех элементов - O (k.ln (n))
Результирующая сложность: O ((n + k) (ln n))) в худшем случае.
Мы не можем предоставить оценку сложности для общего количества входов (n + k), потому что k и n не зависят. Например, если n асимптотически пренебрежимо мало по отношению к k , то общая сложность будет O (k) .
Но если мы предположим, что k = O (n) , то получаем сложность O (n.ln (n)) .
Другие примеры
И если мы переместим обратные кавычки, чтобы посмотреть, что вычисляется, мы увидим, что нам даже не нужно ничего сравнивать (после предварительной обработки первого списка):
Вот еще один пример (взят из комментария):
Эффективная функция:
источник
(LIST* A B C R) should be a lambda expression
.(use-package :optima)
(редактирование ...)optima
. Наконец, код, который я предоставил, должен быть оцениваем.(MAPCAR (EVAL (LAMBDA (X) ...
который оценивает в ответ. Вы оставили там какой-нибудь отладочный код?