자물쇠와 열쇠의 게임


12

번호가 1-n 인 n 개의 상자 가 있습니다 . 각 상자는 하나의 해당 유형의 키 (번호 1-n ) 만 열 수 있도록 잠겨 있습니다 . 이러한 키는 상자에 무작위로 흩어져 있으며 (한 상자에는 여러 개의 키가있을 수 있고, 하나의 키에는 여러 개의 중복이있을 수 있음) 모든 상자가 닫힙니다. 많은 상자에 보물 ( 0 )이 잠겨 있습니다.

모든 보물을 회수하기 위해 자물쇠 제조공을 고용했습니다. 그는 금이 간 상자마다 요금을 청구합니다. 키를 이미 사용할 수있는 상자를 열면 무료입니다.

입력은 각 상자의 내용입니다. 입력 형식을 결정할 수 있습니다.

보물을 얻는 데 필요한 최소 비용을 출력하십시오.

노트

  1. 알고리즘 시간이 오래 걸릴 수 있지만 관련이 없습니다.
  2. 가장 짧은 코드가 승리합니다.
  3. 유효하지 않은 입력에 대해 신경 쓸 필요가 없습니다.

샘플 데이터

여기서 줄 i 는 상자 i 에있는 키를 나타냅니다 .

입력

2 0
3
4 0
5 6 0
6
0

산출

1

입력

2 0
3 0

4 0
6
5 0

산출

3

입력

2 4 0
3 0

1 0
6
5 0

산출

2

입력

1
3 4


2 6
5

산출

0

2
이것은 아마도 이것과 관련 있습니까?
Addison Crump


@VoteToClose 멋진 비디오. 일반화 된 것이 아니라 수학 퍼즐과 특정 알고리즘에 대해 이야기한다는 점을 제외하면 비슷합니다.
ghosts_in_the_code

1
이것은 퍼즐과 관련이있는 것으로 보입니다. 나무와 강철로 된 100 개의 잠긴 상자 : puzzling.stackexchange.com/q/17852/4551
xnor

4
@ghosts_in_the_code 단순성에 관한 것이 아니라 유연성에 관한 것입니다. 일반적으로 구조화 된 입력이 필요한 문제는 데이터가 전처리되지 않는 한 편리한 목록 형식을 허용합니다. 언어와 같이 공백으로 구분 된 파일을 의미 [[1] [3 4] [] [] [2 6] [5]]하거나 의미 하거나 어쩌면 {{1},{3,4},{},{},{2,6},{5}}. 이런 식으로 대부분의 언어는 입력을 사소한 것으로 입력을 줄이고 i=eval(read())도전의 재미있는 부분에 집중할 수 있습니다.
Martin Ender

답변:


6

CJam, 59 52 50 49 45 43 42 바이트

qN/ee::~e!{_0+{0a&}#>W%_{1$|(z@-},,\;}%:e<

3 바이트를 골라 내고 4 개 더 길을 포장 한 @ MartinBüttner에게 감사합니다!

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

qN/      e# Read all input and split it at linefeeds.
ee       e# Enumerate the lines.
         e# STACK: [[0 "i0 i1 ..."] [1 "j0 j1 ..."] ...]
::~      e# Apply ~ (bitwise NOT/evaluate) to each item of the pairs.
         e# STACK: [[-1 i0 i1 ...] [-2 j0 j1 ...] ...]
e!       e# Push all unique permutations of the resulting array.
{        e# For each permutation:
  _0+    e#   Push a copy and append 0 to it.
  {0a&}# e#   Find the first index of an element that contains 0.
  >      e#   Discard all previous elements of the array.
  W%     e#   Reverse the resulting array.
         e#   We now have a (partial) permutation that contains
         e#   all treasures and ends with a treasure.
  _      e#   Push a copy. The original (which contains lists, but no 
              numbers) will serve as accumulator.
  {      e#   Filter; for each list in the array:
    1$|  e#     Push a copy of the accumulator and perform set union.
    (    e#     Shift out the first element (bitwise NOT of 0-based index).
    z    e#     Apply absolute value to push the 1-based index.
    @-   e#     Perform set difference with the former state of the 
         e#     accumulator. This pushes an empty list iff the 1-based
         e#     index was already in the accumulator, i.e., iff we already
         e#     had a key.
  },     e#   Keep the element if we did not have the key.
  ,      e#   Count the kept elements.
  \;     e#   Discard the accumulator from the stack.
}%       e#
:e<      e# Get the minimum of all results.

2
CJam 이해의 선물없이 우리를 위해 설명을 추가해 주시겠습니까? : D 이것이 어떻게 작동하는지 알고 싶습니다.
애디슨 크럼프

2
@VoteToClose이 CJAM101을보십시오
user41805

array long &작품, 그래서 당신은 제거 할 수 있습니다 a에서 0a&. 슬프게도 이것은 당신을 잡기가 약간 어렵게 만듭니다.
피터 테일러

내가 대체 할 경우 @PeterTaylor 불행하게도, 0a&함께 0&, 또한 교체해야 0+와 함께 0aa+있기 때문에, 0 0&falsy입니다.
Dennis

@VoteToClose 내 답변을 편집했습니다.
Dennis

2

CJam (53 바이트)

Nq+N/:a::~:A,_m*_.&{,}$_{{_Af=e_|}:PA,*A,,^0-P0&!}#=,

온라인 통역사에게는 속도가 너무 느립니다.

해부

Nq+N/:a::~:A      e# Parse the input into arrays and store in A
,_m*_.&           e# Generate (with duplicates) a powerset of [0 1 ... n]
{,}$              e# Sort by size
_{                e# Create a copy and search for first index satisfying...
  {_Af=e_|}:P     e#   Store in P a block which does a reachability expansion
  A,*             e#   Apply it n times (no path can be longer than n)
  A,,^0-          e#   Invert to get the unreached nodes (except 0)
  P               e#   Apply P again to see what's reached from the unreached nodes
  0&!             e#   Check that it doesn't include [0]
}#
=,                e# Look up the powerset element at that index and find length

java.lang.OutOfMemoryError: Java heap space프로그램과 함께 받았습니다 .
ŽaMan

@qumonio, 특히 확장 가능하지 않습니다. 질문의 테스트 입력보다 큰 입력으로 테스트하지 않았으므로 표준 1GB 힙에서 얼마나 멀리 갈 수 있는지 잘 모르겠습니다.
피터 테일러

JS에서 배열로 표시된 6 줄을 시도했습니다. [ [4,0], [1,3,4], [0], [6,0], [3,0], [5]]물론 원래 게시물과 같이 입력 스타일이 있습니다.
ŽaMan

@qumonio, 내 컴퓨터에서 128MB의 힙만으로 입력을 잘 처리합니다. 기본적으로보다 적습니다.
피터 테일러

0

하스켈, 173 바이트

l 당신이 전화하고 싶은 사람입니다.

확실하지 나는 사이비를 사용하지 여부를 Map(대신 [(Int,[Int])]대신 [[Int]]).

l=o[].map(map read).map words.lines
o[]b|0`notElem`concat b=0|0<1=1+minimum[o[n]b|n<-[1..length b],b!!(n-1)/=[]]
o(n:k)b=o(filter(/=0)(k++b!!(n-1)))(take(n-1)b++[]:drop n b)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.