펄, 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 11이 아니라 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