https://www.acmicpc.net/problem/2805
알고리즘 분류 : 이분 탐색, 매개 변수 탐색
❓문제
🔅해석
투포인터와 비슷하게 세개의 포인터로 문제를 푼다.
1 ~ 트리의 최대값까지의 배열을 만들어 start = 1, end = 트리의 최대값, mid = (start / end) / 2 로 초기화한다.
mid 값을 현재 절단기 높이라고 생각하고, 입력받은 트리의 순회하면서 mid 값을 각각 빼주고 sum에 더한다.
sum이 목표값보다 크다면 나무를 더 많이 잘랐다는 뜻으로 절단기 높이를 높이기 위해 start 값을 mid + 1로 설정한다.
반대의 경우, end = mid - 1로 설정한다.
다시 mid = (start + end) / 2로 설정해고 위와 같이 트리를 순회하면서 절단된 나무들의 합을 구한다.
이 때, sum == 목표값(M) 된다면, 반복문을 종료한다.
start <= end일 때 mid 값 계산을 하지 못하여 종료를 한다.
⭕정답 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N, M;
static int[] tree;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
tree = new int[N];
int start = 0, end = 0, mid = 0;
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
int num = Integer.parseInt(st.nextToken());
tree[i] = num;
end = Math.max(end, num);
}
int result = 0;
while (start <= end) {
mid = (start + end) / 2;
long sum = 0;
for (int i = 0; i < N; i++) {
int cutLen = tree[i] - mid;
sum += (cutLen <= 0 ? 0 : cutLen);
}
if (sum > M) {
result = mid;
start = mid + 1;
} else if (sum == M) {
result = mid;
break;
} else {
end = mid - 1;
}
}
System.out.println(result);
br.close();
}
}
❗결과
'코딩테스트 > 백준' 카테고리의 다른 글
[코테] 백준 2042번 : 구간 합 구하기 (java) (0) | 2024.08.04 |
---|---|
[코테] 백준 1927번 : 최소 힙 (java) (0) | 2024.08.04 |
[코테] 백준 2003번 : 수들의 합 2 (java) (0) | 2024.08.03 |
[코테] 백준 1713번 : 후보 추천하기 (java) (0) | 2024.08.03 |
[코테] 백준 1256번 : 사전 (java) (0) | 2024.08.03 |