펄, 65 59 55 54 바이트
에 +2 포함 -ap
STDIN에서 트리 크기로 실행하십시오.
for i in `seq 24`; do echo -n "$i: "; vines.pl <<< $i; echo; done
vines.pl
:
#!/usr/bin/perl -ap
$_=map{${"-@F"%$_}|=$_=$$_|$"x$p++.1;/.\b/g}1-$_..-1
설명
나무를 다시 쓰면
3
|
2 4
\ /
1
|
0
각 노드에는 모든 조상과 자체 세트가 포함되어 있습니다.
{3}
|
{2,3} {4}
\ /
\ /
{1,2,3,4}
|
{0,1,2,3,4}
그런 다음 모든 노드를 4에서 3까지의 경로로 설명 할 수 있습니다.
- 3을 포함하지만 4를 포함하지 않는 모든 노드 (3에서 내려 가기)
- 4를 포함하지만 3을 포함하지 않는 모든 노드 (4에서 내려 가기)
- 3과 4를 모두 포함하는 가장 높은 노드 (결합)
모서리 수는 노드 수보다 1이 적으므로이를 사용하여 결합 점을 무시할 수 있으므로 경로가 4에서 3 사이 인 모서리의 수는 3이됩니다.
- 3을 포함하지만 4 : 2를 포함하지 않는 노드 수
- 4를 포함하지만 3 : 1을 포함하지 않는 노드 수
이는 대상으로 직접 내려가는 경로에도 적용됩니다. 예를 들어 3에서 2까지의 경로의 경우 가장자리 수는 1이므로 다음과 같습니다.
- 2를 포함하지만 3 : 3을 포함하지 않는 노드의 수
- 3을 포함하지만 2 : 1을 포함하지 않는 노드의 수
그런 다음 이러한 모든 조합을 요약 할 수 있습니다.
대신 노드 만 봅니다 (예 : 조상이 설정된 노드 2) {2,3}
. 이 노드는 경로를 처리 할 때 2 to 1
1이 아니라 2를 포함하므로 한 번 기여할 것입니다. 경로 3 to 2
는 2와 3을 모두 갖기 때문에 경로 에 아무런 영향을 미치지 않지만 3이 4 to 3
있기 때문에 경로를 처리 할 때는 한 번만 기여합니다. no 4. 일반적으로 노드의 조상 세트에있는 숫자는 세트에없는 각 이웃에 대해 하나씩 기여합니다 (하나는 낮음). 경로가 없기 때문에 낮은 이웃 3에만 기여하는 최대 요소 (이 경우 4)를 제외하고5 to 4
. Simular 0은 한면이지만 0은 항상 트리의 루트에 있고 모든 숫자를 포함하므로 (최종 조인이며 조인을 계산하지 않습니다) 0에서 기여한 부분이 없으므로 노드 0을 떠나는 것이 가장 쉽습니다. 모두 밖으로.
따라서 각 노드의 조상 세트를보고 문제를 계산하고 모든 노드의 합계를 계산하여 문제를 해결할 수도 있습니다.
이웃을 쉽게 처리하기 위해 조상 세트를 공백 문자열로 표시하고 위치 p의 각 1이 n-1-p가 조상임을 나타내는 1을 나타냅니다. 예를 들어 n=5
위치 0에서 1 의 경우 4는 조상임을 나타냅니다. 후행 공백을 남기겠습니다. 따라서 내가 만들 트리의 실제 표현은 다음과 같습니다.
" 1"
|
" 11" "1"
\ /
\ /
"1111"
노드 0 "11111"
을 무시할 것이므로 표시되는 노드 0을 제외했습니다 (기여하지 않음).
낮은 이웃이없는 조상은 이제 1의 시퀀스 끝으로 표시됩니다. 더 높은 이웃이없는 조상은 이제 1의 시퀀스 시작으로 표시되지만 5 to 4
존재하지 않는 경로 를 나타내므로 문자열 시작시 시퀀스의 시작을 무시해야 합니다. 이 조합은 정규식과 정확히 일치합니다 /.\b/
.
조상 문자열 만들기는 모든 노드를 순서대로 처리 n-1 .. 1
하고 노드 자체의 위치에 1을 설정하고 자손에 "또는"을 수행하여 수행합니다.
프로그램이 이해하기에 충분히 쉬운 모든 것 :
-ap read STDIN into $_ and @F
map{ }1-$_..-1 Process from n-1 to 1,
but use the negative
values so we can use a
perl sequence.
I will keep the current
ancestor for node $i in
global ${-$i} (another
reason to use negative
values since $1, $2 etc.
are read-only
$$_|$"x$p++.1 "Or" the current node
position into its ancestor
accumulator
$_= Assign the ancestor string
to $_. This will overwrite
the current counter value
but that has no influence
on the following counter
values
${"-@F"%$_}|= Merge the current node
ancestor string into the
successor
Notice that because this
is an |= the index
calculation was done
before the assignment
to $_ so $_ is still -i.
-n % -i = - (n % i), so
this is indeed the proper
index
/.\b/g As explained above this
gives the list of missing
higher and lower neighbours
but skips the start
$_= A map in scalar context
counts the number of
elements, so this assigns
the grand total to $_.
The -p implicitly prints
공지 것으로 교체 /.\b/
하여 /\b/
이 문제를 해결합니다의 왕복 타잔 버전은 또한 경로를 얻어 여기서0 to n-1
조상 문자열이 어떻게 보이는지에 대한 몇 가지 예 (순서대로 n-1 .. 1
) :
n=23:
1
1
1
1
1
1
1
1
1
1
1
11
1 1
1 1
1 1
11 11
1 1
11 1 1 11
1 1
1111 11 11 1111
111111111 111111111
1111111111111111111111
edges=68
n=24:
1
1
1
1
1
1
1
1
1
1
1
1
1 1
1 1
1 1
1 1
1 1
1 1 1 1
1 1
11 1 1 11
1 1 1 1
1 1 1 1
1 1
edges=82