Прибыль в магазине игрушек

15

История

«2016? Хорошо ...», проворчал продавец игрушек Гильберт. Он открыл глаза, вытер салфетку, стекающую с его уха, и съел утренний клич-крем. Образцы праздников. Он должен пойти на работу сейчас и закончить бухгалтерский учет за год.

Рождество - очень урожайный период года, особенно для его продаж. Гильберт точно знает, как это работает: человек приходит в магазин и покупает первый подарок, который ему предлагают. Они платят за это и убегают в другой магазин. На практике то, что на самом деле является даром, на самом деле не имеет значения. Цена также не имеет значения, если она не слишком высока. Все зависит от времени, оставшегося до Рождества - чем короче время, тем больше угрызения совести у покупателей, тем больше цена, которую они готовы заплатить.

Все, что нужно Гилберту, это посмотреть на его часы - и он сразу знает, сколько могут потратить его клиенты. Он может легко воспользоваться этим фактом: он просто находит самый дорогой подарок, который он может продать данному клиенту, и предлагает его им. Только теперь он понял, что забыл применить эту хитрую стратегию в прошлом году. Это изменится хотя!

Тем не менее, Гильберт хотел бы знать, насколько процветал бы его бизнес, если бы он действительно использовал свою грандиозную схему. Ему удалось составить список людей, которые пришли в его магазин, однако он не уверен, сколько денег он мог бы заработать на них.

Ваша задача (TL; DR)

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

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

Вы получаете -40%бонус персонажа, если асимптотическая сложность времени вашего алгоритма O(n+m)(а не тривиальная O(n*m)) Где n, mдлины входных списков.

Это , выигрывают короткие байты. Стандартные лазейки запрещены.

пример

Входные данные:

1 2 2 2 5 7 10 20
1 1 2 3 6 6 15 21 21 22

Выход:

1 0 2 2 5 2 10 20 7 0

Это задание было взято с местного конкурса программистов и переведено мной на английский язык. Вот оригинальное задание: https://www.ksp.sk/ulohy/zadania/1131/

sammko
источник
9
Бонусы - это одна вещь, которую следует избегать при написании задач . Тем не менее, я думаю, что это может быть хорошо здесь. Если вы хотите сохранить его, я рекомендую изменить его на процентный бонус. Бонус в 20 символов ничего не значит для представления Java, но в основном обязателен для решений на языке игры в гольф.
Денкер
Могу ли я наградить OP за вознаграждение только за предысторию? Честно говоря, это заставило меня улыбнуться; каждый вызов нуждается в одном из них.
кот
@tac Спасибо, но, как отмечается в небольшом тексте внизу, я фактически не создавал предысторию - я только перевел ее.
Саммко
@ sammko да, я видел это, но мой вышеупомянутый комментарий все еще остается :)
кошка

Ответы:

5

Pyth, 17 16 байт

1 байт благодаря Pietu1998

VE=.-Q]
e|fgNTQ0

демонстрация

Объяснение:

VE=.-Q]<\n>e|fgNTQ0
                        Implicit: Q is the list of prices.
VE                      For N in the list of budgets
             f   Q      Filter the list of prices
              gNT       On the current person's budget being >= that price
            |     0     If there aren't any, use 0 instead.
          e             Take the last (most expensive) value.
      <\n>              Print it out.
  =.-Q                  Remove it from the list of prices.
isaacg
источник
Я думаю, вы можете сохранить 1 байт с помощью VE=.-Q]\ n e|fgNTQ0. В основном то же самое, но с петлей.
PurkkaKoodari
4

Haskell, 67 байт

a#(b:c)|(h,t)<-span(<=b)a=last(0:h):(init(h++[0|h==[]])++t)#c
_#x=x

Пример использования: [1,2,2,2,5,7,10,20] # [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Разделите цены на две части: (h,t)где hвсе цены <= бюджет следующего покупателя и tвсе остальные. Возьмите последнюю цену hи продолжайте рекурсивно со всеми, кроме последнего из hплюса tи оставшихся бюджетов. last(0:h)оценивает, 0если hпусто. Аналогично: init (h++[0|h==[]]) ++ tдобавляет фиктивный элемент 0в hif, если hон пуст, так что ему initесть что отбросить ( initошибка в пустом списке).

Ними
источник
3

Java, 154 * 0,6 = 92,4 байта

-13 байт, потому что лямбда может на самом деле использовать int[], а не Integer[](спасибо BunjiquoBianco )

Это должно занять O (n + m) времени и O (n + m) дополнительного пространства (при условии, что я понимаю большие обозначения O) .

g->b->{int l=g.length,L=b.length,G=0,B=0,A=0;int[]a=new int[l],s=new int[L];for(;B<L;){while(G<l&&g[G]<=b[B])a[A++]=g[G++];s[B++]=A>0?a[--A]:0;}return s;}

С отступом: ( Попробуйте онлайн! )

static int[] toyStore(int[]g,int[]b) {
    int gl=g.length,bl=b.length,gp=0,bp=0,ap=0;
    int[] a=new int[gl],s=new int[bl];
    for (;bp<bl;) {
        while(gp<gl&&g[gp]<=b[bp])a[ap++]=g[gp++];
        s[bp++]=ap>0?a[--ap]:0;
    }
    return s;
}

public static void main(String[] args)
{
    System.out.println(Arrays.toString(
        toyStore(new int[] {1,2,2,2,5,7,10,20},
                 new int[] {1,1,2,3,6,6,15,21,21,22})
        ));
}

Я показываю не лямбда-разложение здесь, потому что объявление типа чище, и это та же самая логика. Лямбда присутствует в идоне связи.

Объяснение:

Используемые переменные:

  • gсписок цен на подарки, bсписок бюджетов.
  • glэто длина gи blэто длина b.
  • aэто стек для доступных подарков, sэто выходной массив проданных подарков.
  • gp, bpИ apявляются указателями для g, bи aсоответственно. bpтакже указатель для s.

Алгоритм:

  • Для каждого бюджета в длине бюджетов
    • Пока этот бюджет можно купить в подарок на g[gp]
      • Вставьте бюджет в стек aи увеличивайтеgp
    • Поп верх aв , s[bp]если она существует, то еще положить 0.
CAD97
источник
Вы не можете карри лямбда? (т.е. (g,b)->к g->b->?
ASCII-только
@ Кто-то, очевидно, да. По некоторым причинам это никогда не работало для меня прежде, но теперь это будет. 0.o (Вы сэкономили 0,6 байта после бонуса.)
CAD97
Вы можете сохранить несколько байтов, используя long, если предполагается, что ввод будет длинным [] (занимает 158 байт) - ideone.com/invHlc
BunjiquoBianco
1
@BunjiquoBianco на самом деле я могу просто использовать int []. По какой-то причине у меня сложилось впечатление, что, поскольку аргументы типа принимают ссылочные типы (а не примитивы с типизированным значением int), мне нужно было использовать массив ссылочных типов. Но я могу использовать массив int просто отлично. Я обновлю, как только получу шанс.
CAD97
@ CAD97 Ха! Не могу поверить, что я не сделал эту ссылку ...
BunjiquoBianco
2

Haskell, 87 * 0,6 = 52,2 байта

g s(p:q)d@(b:c)|p<=b=g(p:s)q d
g[]p(b:c)=0:g[]p c
g(s:t)p(b:c)=s:g t p c
g _ _ _=[]
g[]

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

Последняя строка (-> g[]) не является частью определения, но вызывает накладные расходы. Пример использования: g [] [1,2,2,2,5,7,10,20] [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Работает в основном так же, как ответ @ CAD97 , т. Е. Использует (изначально пустой) вспомогательный стек для отслеживания покупаемых предметов. Подробно: проверьте по порядку:

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

Это работает во m+nвремени, потому что a) операции со вспомогательным стеком используют постоянное время и b) в каждом из рекурсивных вызовов один из списков укорачивается на один элемент.

Ними
источник
2

Желе , 15 байт

ṀṄ;©®œ^
Rf@€ç/Ṁ

Попробуйте онлайн!

Как это устроено

ṀṄ;©®œ^  Helper link. Arguments: G, H (lists of affordable gifts)

Ṁ        Compute the maximum of G (0 if the list is empty).
 Ṅ       Print it.
  ; ®    Concatenate it with the register (initially 0).
   ©     Save the result in the register.
     œ^  Compute the multiset symmetric difference of the updated register and H.

Rf@€ç/Ṁ  Main link. Arguments: B (budgets), P (prices)

R        Range; replace each t in B with [1, ..., t].
 f@€     Intersect the list of prices with each budget range, obtaining, for each
         customer, the list of all gifts he's willing to pay for.
    ç/   Reduce the array of lists by the helper link.
         In each iteration, this computes and prints the most expensive gift for
         a customer, than removes the selected gift (and all previously
         selected gifts) from the next list.
      Ṁ  Compute the maximum of the resulting list, which corresponds to the last
         customer.
Деннис
источник
1

JavaScript, 85 * 0,6 = 51 байт

f=(a,b,s=[],[t,...u]=a,[v,...w]=b)=>v?t<=v?f(u,b,[...s,t]):[s.pop()|0,...f(a),w,s)]:[]

Еще один клон ответа @ CAD97.

Нил
источник