백준9934 - 완전 이진 트리(Java)

2024. 3. 1. 16:15·알고리즘/문제풀이
728x90

https://www.acmicpc.net/problem/9934

 

9934번: 완전 이진 트리

상근이는 슬로베니아의 도시 Donji Andrijevci를 여행하고 있다. 이 도시의 도로는 깊이가 K인 완전 이진 트리를 이루고 있다. 깊이가 K인 완전 이진 트리는 총 2K-1개의 노드로 이루어져 있다. (아래

www.acmicpc.net

재귀 문제를 풀어보았다.
문제는 길지만 정리하면 완전 이진 트리의 값이 주어지고, 이 트리를 레벨별로 출력하는 문제였다.

입력이 항상 완전 이진트리임이 보장되기 때문에, 전위 순회를 진행시키고 방문 순서대로 StringBuilder에 append하는 방식으로 풀어주었다.

 

높이가 4인 완전 이진 트리를 예시로 생각해보자

  • 전체 노드의 개수는 2^4 - 1 개이다.
  • 루트 노드의 인덱스는 가운데에 있는 8, 즉 2^(4-1) 이다.

그러면 루트 노드 기준으로 높이가 3인 두 개의 완전 이진 트리형태의 서브트리로 분리된다.
두 개의 서브트리는 다음과 같다.

  • 전체 노드의 개수는 2^3 - 1 개이다.
  • 루트 노드의 인덱스는 각각 4 / 12이다.

여기서 점화식을 도출해낼 수 있다.

높이가 n인 완전 이진트리의 경우
- 전체 노드의 개수는 2^n - 1개이다.
- 루트 노드의 인덱스는 2^(n-1) 이다.
- 서브트리의 루트 노드 인덱스는 이전 트리의 루트 노드 인덱스 +- 2^(트리 레벨과 반비례하는 값) 

자식 노드와의 인덱스가 1씩 차이날때까지 진행해주면 되는데, 트리의 총 높이와 현재 레벨(h)의 값이 같을 때까지 진행해주면 된다.

2의 n승의 경우 비트를 통해 계산하면 편하므로 다음과 같이 코드를 짜보았다.

 

package BOJ;

import java.io.*;
import java.util.*;

public class BOJ9934 {

    private static int[] arr;
    private static StringBuilder[] builders;
    private static int K;

    public static void main(String[] args) throws IOException {
        init();

        // 루트 노드 인덱스 : 1 << (K - 1)
        // 시작 높이 : 1 (최상단)
        go(K == 1 ? 1 : (1 << (K - 1)), 1);

        print();
    }

    private static void go(int n, int h) {
        if (K < h) return;
        builders[h - 1].append(arr[n]).append(" ");

        go(n - (1 << (K - h - 1)), h + 1);
        go(n + (1 << (K - h - 1)), h + 1);
    }

    private static void print() {
        for (int i = 0; i < K; i++) {
            System.out.println(builders[i].toString().trim());
        }
    }

    private static void init() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        K = parse(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        arr = new int[1 << K];
        builders = new StringBuilder[K];
        for (int i = 0; i < K; i++) {
            builders[i] = new StringBuilder();
        }
        for (int i = 1; i < arr.length; i++) {
            arr[i] = parse(st.nextToken());
        } // end init
    }

    private static int parse(String s) {
        return Integer.parseInt(s);
    }
}
저작자표시 (새창열림)

'알고리즘 > 문제풀이' 카테고리의 다른 글

백준6593: 상범 빌딩(Java)  (0) 2024.03.13
백준12919 : A와 B 2  (0) 2024.02.27
백준9184: 신나는 함수 실행(Java)  (0) 2024.02.27
백준4179 : 불!  (0) 2023.09.19
백준17106 : 빙고  (0) 2023.06.20
'알고리즘/문제풀이' 카테고리의 다른 글
  • 백준6593: 상범 빌딩(Java)
  • 백준12919 : A와 B 2
  • 백준9184: 신나는 함수 실행(Java)
  • 백준4179 : 불!
kkap999
kkap999
IT에 관심 가득한 갑갑이의 개발&스터디 블로그
  • kkap999
    갑갑이의 개발세상
    kkap999
    • 분류 전체보기 (95)
      • Backend (1)
        • Java&Spring&Servlet (8)
        • DB (0)
      • 알고리즘 (78)
        • 문제풀이 (70)
        • 자료구조 (6)
        • 그 외 (2)
      • App&FE (3)
        • FE (1)
        • Flutter (2)
      • Computer Science (0)
        • 네트워크 (0)
        • 컴퓨터기초 (0)
      • Cloud (0)
        • AWS (0)
        • Azure (0)
        • gcp (0)
      • 잡담&일상 (4)
        • 일상 (1)
        • 잡담 (2)
        • 음악 (1)
  • 태그

    백준
    알고리즘
    N과M(1)
    BOJ
    BOJ15649
  • 링크

    • github
  • 인기 글

  • 최근 글

  • 07-03 07:39
  • 전체
    오늘
    어제
  • 반응형
  • hELLO· Designed By정상우.v4.10.3
kkap999
백준9934 - 완전 이진 트리(Java)
상단으로

티스토리툴바