ペアコンデンサ


12

コンデンサは高い公差で製造されていることで有名です。これは多くの場合許容されますが、許容範囲の厳しいキャパシティが必要になる場合があります。必要な正確な値で容量を取得する一般的な戦略は、慎重に測定した2つのコンデンサを並列に使用して、容量が必要な範囲内になるようにすることです。

この課題の目標は、(複数の)容量のセットが与えられ、各ペアの合計容量が所定の範囲内になるようにコンデンサをペアにすることです。また、最適なペアリングのセット、つまり、できるだけ多くのペアが見つかるようなペアリングのセットを見つける必要があります。

制約

  1. 入力は選択した形式で構成されます
    • 持っているコンデンサの(複数の)セットを表す容量の順序なしリスト
    • ターゲット範囲の下限と上限を表す容量のペア(包括的)
  2. 入力のすべての容量は2 30より小さい正の整数であり、単位はpFです(それは重要ではありません)。
  3. 入力の容量のリストに加えて、所有するコンデンサのセットには、値が0 pFのコンデンサが無限に含まれています。
  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 pFのペアにします。残りを並べ替えます。これが範囲を超えている場合は最低と最高のコンデンサをペアにしてください。
orlp

1
いくつかの入出力テストがいいでしょう。
orlp

@orlp私はすでに尋ねました、OPはそれに取り組んでいます
ベータ崩壊

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

Python 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)]

通常のコンデンサごとに1つの0 pFコンデンサを追加します。次に、コンデンサを並べ替え、最低と最高のコンデンサをペアリングし続けます。合計が許容範囲内である場合、それを印刷し、範囲を超える場合は最高を破棄し、下限を下回る場合は最低を破棄します。

入力/出力の例:

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

0 90
20 80
30 70
40 60
40 50
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.