728x90
https://www.acmicpc.net/problem/2957
문제
이진 탐색 트리는 모든 노드가 많아야 2개의 자식 노드를 가지고 있는 트리이고, 각 노드에는 수가 하나씩 쓰여있다. 만약 어떤 노드에 쓰여 있는 수가 X라면, 그 노드의 왼쪽 서브트리에는 X보다 작은 수, 오른쪽 서브트리에는 X보다 큰 수만 저장되어 있어야 한다.
1보다 크거나 같고, N보다 작거나 같은 수 N개가 한 번씩 등장하는 수열이 입력으로 주어진다. 이 수열을 이용해서 이진 탐색 트리를 만들려고 한다. 이제 배열의 첫 번째 수를 루트 노드로 놓고, 다른 나머지 수들을 순서대로 삽입하면서 이진 탐색 트리를 만들려고 한다. 즉, 첫 번째 수를 제외한 모든 수에 대해서 insert(X,root)를 실행하는 것과 같다. 그 함수는 다음과 같다.
이진 탐색 트리에 삽입하는 함수는 다음과 같다.
insert(number X, node N)
카운터 C값을 1 증가시킨다
if X가 노드 N에 있는 수보다 작다면
if N의 왼쪽 자식이 없다면
X를 포함하는 새 노드를 만든 뒤, N의 왼쪽 자식으로 만든다
else
insert(X, N의 왼쪽 자식)
else (X가 노드 N에 있는 수보다 크다면)
if N의 오른쪽 자식이 없다면
X를 포함하는 새 노드를 만든 뒤, N의 오른쪽 자식으로 만들기
else
insert(X, N의 오른쪽 자식)
각 수를 삽입한 후에 C의 값을 출력하는 프로그램을 작성하시오. 카운터 C의 값은 0으로 초기화되어 있다.
입력
첫째 줄에 수열의 크기 N이 주어진다. (1 ≤ N ≤ 300,000)
다음 N개의 줄에는 수열의 수가 차례대로 주어진다. 수는 구간 [1, N]에 포함된 정수이고, 중복되지 않는다.
출력
N개의 줄에 각 수가 트리에 삽입된 후에 카운터 C값을 한 줄에 하나씩 출력한다.
728x90
예제 입력 1
4
1
2
3
4
예제 출력 1
0
1
3
6
예제 입력 2
5
3
2
4
1
5
예제 출력 2
0
1
2
4
6
예제 입력 3
8
3
5
1
6
8
7
2
4
예제 출력 3
0
1
2
4
7
11
13
15
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.TreeMap;
public class Main {
static long c;
static TreeMap<Integer, Integer> tm = new TreeMap<>();
static StringBuilder sb = new StringBuilder();
private static void insert(int x) {
if(tm.size() == 0) { // 루트 노드를 아직 넣지 않았다면
tm.put(x, 0); // 루트 노드 넣어줌(key는 정수, value는 depth)
sb.append("0\n");
return;
}
tm.put(x, 0); // TreeMap에 x를 넣어줌
// 부모 노드의 depth를 구한다
// 부모는 현재 노드보다 큰 수 중 가장 작거나, 작은 수 중 가장 큰 수
int parent = 0;
if(tm.lowerKey(x) == null) { // 자신보다 작은 수가 없으면 부모가 현재 노드보다 큰 수 중 가장 작은 수라면
parent = tm.higherKey(x); // 부모의 값을 가져온다
}
else if(tm.higherKey(x) == null){ // 자신보다 큰 수가 없으면 부모가 현재 노드보다 작은 수 중 가장 큰 수라면
parent = tm.lowerKey(x); // 부모의 값을 가져온다
}
else { // 둘 다 있다면 parent는 depth가 높은 것
parent = tm.get(tm.higherKey(x)) > tm.get(tm.lowerKey(x)) ? tm.higherKey(x) : tm.lowerKey(x);
}
int parentDepth = tm.get(parent); // 부모의 depth를 구하고
c += parentDepth + 1; // 루트 노드에서부터 x까지 오려면 parent의 depth에서 한 칸 더 내려와야 한다.
tm.put(x, parentDepth + 1); // x의 Depth도 바꿔줌
// 현재의 c값 출력
sb.append(c + "\n");
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 수열의 크기 N 입력
int N = Integer.parseInt(br.readLine());
// N개의 수 트리에 넣기
for (int i = 0; i < N; i++) {
insert(Integer.parseInt(br.readLine()));
}
// 출력
System.out.println(sb);
}
}
728x90
'Problem Solving > BOJ' 카테고리의 다른 글
[백준, BOJ 17135] 캐슬 디펜스 (java) (0) | 2023.02.25 |
---|---|
[백준, BOJ 1260] DFS와 BFS (java) (0) | 2023.02.25 |
[백준, BOJ 7662] 이중 우선순위 큐 (java) (0) | 2023.02.22 |
[백준, BOJ 13975] 파일 합치기 3 (java) (0) | 2023.02.22 |
[백준, BOJ 16472] 고냥이 (java) (0) | 2023.02.22 |