[ 백준 ] 9934 / 완전 이진 트리

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
123/228
post-thumbnail
post-custom-banner

# Appreciation

/*
 * Problem :: 9934 / 완전 이진 트리
 *
 * Kind :: Data Structure
 *
 * Insight
 * - 도시를 방문한 순서 = 중위 순회
 *   + 레벨 i의 루트노드 = RN_i
 *     레벨 i의 왼쪽 서브트리 = LST_i
 *     레벨 i의 오른쪽 서브트리 = RST_i
 *     레벨 i의 오른쪽 서브트리의 왼쪽 서브트리 = RLST_i
 *     레벨 i의 오른쪽 서브트리의 왼쪽 서브트리의 왼쪽 서브트리 = RLLST_i
 *     # LST_1 - RN_1 - RST_1
 *       LST_1 => LLST_2 - RN_2 - LRST_2
 *       RST_1 => RLST_2 - RN_2 - RRST_2
 *       -> (LLST_2 - RN_2 - LRST_2) - RN_1 - (RLST_2 - RN_2 - RRST_2)
 *
 *     #  1
 *       2 3 => 2 - 1 - 3
 *
 *     #    3
 *        6   2
 *       1 4 5 7 =>  6 - 3 - 2  => (1 - 6 - 4) - 3 - (5 - 2 - 7)
 *                  1 4     5 7
 *
 *       -> 서브트리를 방문할 때마다 레벨이 하나씩 증가한다
 *          완전 이진 트리이므로 중위 순회한 빌딩의 개수는 항상 홀수이다
 *          빌딩을 중위 순회한 결과에서 가운데 빌딩의 번호가 루트노드이다
 *          루트노드를 기준으로 왼편에 있는 중위 순회한 결과가
 *          왼쪽 서브트리를 중위 순회한 결과이다
 *          루트노드를 기준으로 오른편에 있는 중위 순회한 결과가
 *          오른쪽 서브트리를 중위 순회한 결과이다
 *          => 재귀적으로 방문해주자!
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

#define endl '\n'

// Set up : Global Variables
int K;
int A[1023+1];
vector<int> L[10+1];

// Set up : Functions Declaration
void f(int s, int e, int lev);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    cin >> K;
    int S = pow(2,K)-1; /* 빌딩의 개수 */
    for (int i=1; i<=S; i++)
        cin >> A[i];

    // Process
    f(1, S, 1);

    // Control : Output
    for (int i=1; i<=K; i++) {
        for (int n : L[i]) {
            cout << n << ' ';
        } cout << endl;
    }
}

// Helper Functions
void f(int s, int e, int lev)
/* s = 중위 순회 결과의 시작 인덱스
 * e = 중위 순회 결과의 종료 인덱스
 * 현재 (서브)트리의 중위 순회 결과 = A[s], A[s+1], ..., A[e-1], A[e]
 * 현재 (서브)트리의 레벨 = lev */
{
    int m = (s+e) / 2; /* 중위 순회 결과의 가운데 인덱스 */
    L[lev].push_back(A[m]); /* L[i] = 레벨 i인 빌딩의 번호들 */
    if (s == e) return;

    f(s, m-1, lev+1); /* 왼쪽 서브트리 */
    f(m+1, e, lev+1); /* 오른쪽 서브트리 */
}
profile
이런 미친 게임을 봤나! - 옥냥이
post-custom-banner

0개의 댓글