페어 커패시터


12

커패시터는 높은 공차로 제조되는 것으로 유명합니다. 많은 경우에 허용되지만 허용 오차가 적은 용량이 필요한 경우도 있습니다. 필요한 정확한 값으로 용량을 얻는 일반적인 전략은 신중하게 측정 된 커패시터 2 개를 병렬로 사용하여 용량이 필요한 범위 내에서 추가되도록하는 것입니다.

이 과제의 목표는 (복수) 용량 세트가 주어지면 각 쌍의 총 용량이 주어진 범위에 있도록 커패시터를 쌍으로 묶는 것입니다. 또한 최상의 페어링 세트, 즉 가능한 많은 쌍을 찾을 수있는 페어링 세트를 찾아야합니다.

제약

  1. 입력은 선택한 형식으로 구성
    • 보유한 (다중) 커패시터 세트를 나타내는 정렬되지 않은 용량 목록
    • 대상 범위 의 하한 및 상한을 나타내는 한 쌍의 용량 (포함)
  2. 입력의 모든 용량은 2 30 보다 작은 양의 정수 이며, 단위는 pF입니다 (중요하지 않음).
  3. 입력의 용량 목록 외에도 보유한 커패시터 세트 에는 값이 0pF 인 무한량의 커패시터가 포함되어 있습니다.
  4. 출력은 각 쌍의 합이 지정된 목표 범위 에 있도록 용량 쌍 목록을 선택한 형식으로 구성 합니다. 쌍의 순서 또는 쌍의 용량 순서가 지정되지 않았습니다.
  5. 보유한 커패시터 세트에 표시되는 것보다 출력에 용량이 더 자주 나타나지 않을 수 있습니다 . 즉, 출력하는 쌍이 겹치지 않아야합니다.
  6. 프로그램이 생성하는 출력보다 더 많은 용량 쌍을 포함하는 조건 4와 5를 만족하는 가능한 출력이 없어야합니다.
  7. 프로그램은 O ( n !) 시간 안에 종료해야합니다 . 여기서 n보유한 커패시터 세트를 나타내는 목록의 길이입니다.
  8. 허점은 남용되지 않아야한다
  9. 대상 범위는 비어을지지 않습니다

채점

점수는 솔루션의 길이 (옥텟)입니다. 솔루션이 일부 k에 대해 다항식 시간 O ( n 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와 1로 페어링하십시오. 나머지를 정렬하십시오. 가장 낮은 커패시터와 가장 높은 커패시터를 계속 연결하십시오.이 범위보다 높은 경우 가장 높은 값을 버립니다. 아래의 가장 낮은 값을 버립니다.
orlp

1
일부 입출력 테스트가 좋을 것입니다.
orlp

@orlp 이미 요청했지만 OP가 작동 중입니다.
Beta Decay

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

한 번 파이썬 골프 :

(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 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.