Пара конденсаторів


12

Конденсатори відомі тим, що виготовляються з високими допусками. Це прийнятно у багатьох випадках, але іноді потрібна ємність із жорсткими допусками. Загальна стратегія отримання ємності з точним значенням, яке вам потрібно, - це використовувати два ретельно виміряні конденсатори паралельно таким чином, щоб їх ємність доповнювала щось у потрібному діапазоні.

Мета цього завдання полягає в тому, щоб, задавши (багато) набір ємностей, з'єднати конденсатори таким чином, щоб загальна ємність кожної пари знаходилася в заданому діапазоні. Вам також потрібно знайти найкращий набір пар, тобто такий набір пар, що знайдеться якомога більше пар.

Обмеження

  1. Введення складається у виборі формату
    • невпорядкований перелік ємностей, що представляють (багато) набір конденсаторів
    • пара ємностей, що представляють нижню і верхню межу цільового діапазону (включно)
  2. всі ємності на вході мають натуральні цілі, менші за 2 30 , одиниця - pF (це не важливо).
  3. Окрім переліку ємностей на вході, набір у вас конденсаторів містить також нескінченну кількість конденсаторів зі значенням 0 пФ.
  4. Вихідні дані містять у форматі вибору перелік пар ємностей таким чином, що сума кожної пари знаходиться у вказаному цільовому діапазоні . Ні порядок пар, ні порядок ємностей у парі не вказано.
  5. Жодна ємність на виході може з’являтися частіше, ніж це відображається в наборі конденсаторів . Іншими словами: виведені пари не повинні перетинатися.
  6. Не повинно бути можливого виходу, що відповідає умовам 4 і 5, що містить більше пар потужностей, ніж вихід, який виробляє ваша програма.
  7. Ваша програма припиняється через O ( n !) Час, де n - довжина списку, що представляє набір наявних конденсаторів
  8. Лазівками не слід зловживати
  9. Цільовий діапазон не повинен бути порожнім

Оцінка балів

Ваш бал - це тривалість вашого рішення в октетах. Якщо вашому рішенню вдасться вирішити цю задачу в поліноміальний час O ( n k ) на деякий k , розділіть свою оцінку на 10. Я не знаю, чи реально це можливо.

Зразок введення

  • діапазон 100 до 100, вхідний масив 100 100 100, допустимий вихід:

    0 100
    0 100
    0 100
    
  • діапазон 100-120, вхідний масив 20 80 100, допустимий вихід:

    0 100
    20 80
    

    вихід 20 100недійсний

  • діапазон 90 до 100, вхідний масив 50 20 40 90 80 30 60 70 40, допустимий вихід:

    0 90
    20 80
    30 70
    40 60
    40 50
    
  • діапазон від 90 до 90, вхідний масив 20 30 40 40 50 60 70 80 90, допустимий вихід:

    0 90
    20 70
    30 60
    40 50
    
  • діапазон від 90 до 110, вхідний масив 40 60 50, допустимий вихід:

    40 60
    

3
Я впевнений, що це легко вирішити в O (n log n). По-перше, з'єднайте будь-який конденсатор в діапазоні до одного з 0 пФ. Сортуйте решту. Продовжуйте спарювати найнижчий і найвищий конденсатор, якщо це вище діапазону, відмовтеся від найвищого, якщо він нижче, відкиньте найнижчий.
orlp

1
Деякі тести на введення / виведення було б непогано.
orlp

@orlp Я вже запитував, ОП працює над цим
бета-розпад

2
Алгоритм @ orlp працює, але доказ довгий коментар. По суті, мінімальний контрприклад повинен мати a <= b <= c <= dтакі, які a + d, a + c, b + dзнаходяться в межах, але b + cнемає, але це суперечить.
Пітер Тейлор

@orlp Чи корисний вам поданий зразок?
FUZxxl

Відповіді:


1

CJam, 5.6

Це пряма повторна реалізація алгоритму у відповідь orlp . Якщо ви підтримуєте мою відповідь, будь ласка, переконайтесь, що ви також схвалюєте цю відповідь . Я також пропоную прийняти відповідь з оригінальним алгоритмом, тому що я дуже сумніваюся, що я зрозумів би, як це витончено вирішити в O (n * log (n)).

l~_,0a*+${(\)@_2$+4$~2$\>{;;\;\+}{<{;+}{oSop}?}?_,1>}g;;

Спробуйте в Інтернеті

Зразок введення:

[90 100] [50 20 40 90 80 30 60 70 40]

Пояснення:

l~      Get and interpret input.
_,      Get length of resistor list.
0a*+    Append the same number of 0 values.
$       Sort the list.
{       Loop until less than 2 entries in list.
  (       Pop off first value.
  \)      Pop off last value.
  @_      Pull first value to top, and copy it.
  2$      Copy last value to top.
  +       Add first and last value.
  4$~     Copy specified range to top, and unwrap the two values.
  2$      Copy sum to top.
  \>      Swap and compare for sum to be higher than top of range.
  {       It's higher.
    ;;\;    Some stack cleanup.
    \+      Put first value back to start of resistor list.
  }
  {       Not higher, so two cases left: value is in range, or lower.
    <       Compare if sum is lower than bottom of range.
    {       It's lower.
      ;+      Clean up stack and put last value back to end of resistor list.
    }
    {       Inside range, time to produce some output.
      o       Output first value.
      So      Output space.
      p       Output second value and newline.
    }?      Ternary operator for comparison with lower limit.
  }?      Ternary operator for comparison with upper limit.
  _,      Get length of remaining resistor list.
  1>      Check if greater 1.
}g      End of while loop for processing resistor list.
;;      Clean up stack, output was generated on the fly.

Ви можете змінити формат виводу, щоб він був більш відповідним для вашої мови. Точний формат виводу не вказаний, є лише ті дані, які ви повинні вивести.
FUZxxl

6

Пітон 2, 11.5

Гольф Python за один раз:

(a,b),l=input()
l=[0]*len(l)+sorted(l)
while l:
 e=l[0]+l[-1]
 if a<=e<=b:print l[0],l[-1]
 l=l[e<=b:len(l)-(a<=e)]

Я додаю один конденсатор 0 пФ для кожного звичайного, більше ніколи не потрібен. Потім ми сортуємо конденсатори і продовжуємо спарювати найнижчий і найвищий конденсатор. Якщо сума знаходиться в межах допустимого діапазону, ми друкуємо її, якщо вона вище діапазону, ми відкидаємо найвищу, якщо вона нижче відкидає найнижчу.

Приклад введення / виводу:

[[90,100], [20,30,40,40,50,60,70,80,90]]

0 90
20 80
30 70
40 60
40 50
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.