본문 바로가기
알고리즘

[JAVA]백준 2805번: 나무 자르기

by Kwoncorin 2021. 7. 21.
728x90

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

 

2805번: 나무 자르기

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000) 둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보

www.acmicpc.net

 

1. 문제 설명

 

상근이는 나무 M 미터가 필요해서 나무들을 잘라서 나무를 구할 것이다.

 

상근이가 절단기에 높이 H를 설정하면 톱날이 H미터 위로 올라가며 한 줄에 연속해 있는 나무들을 모두 절단한다.

 

상근이는 나무를 필요한 만큼만 집으로 가져가려고 할 때, 적어도 M 미터의 나무를 집에 가져가기 위해서 절단기에 설정할 수 있는 높이의 최댓값을 구하는 문제.

 

2. 풀이

 

upper bound를 변형해서 풀 수 있는 문제이다.

 

집에 가져갈 수 있는 나무의 길이는 높이가 0일때부터 내림차순으로 정렬된 것과 같다.

 

따라서 적어도 M 미터의 나무를 집에 가져가기 위해 절단기에 설정할 수 있는 높이의 최댓값은 가장 처음 M 미터 보다 작은 나무를 가질 수 있는 높이의 -1이다.

 

높이의 합을 구하는 부분은 long으로 작성했다.

 

나무의 최대 개수가 1,000,000이고 최대 높이가 1,000,000,000 이기에 계산하는 부분에서 int의 범위를 초과할 수 있다.

 

*로직

- 이분탐색

- mid 높이 값으로 설정했을 때 가질 수 있는 나무의 길이가 M 보다 작은 경우 e=mid로 설정

- 나무의 길이가 M보다 크거나 같을 경우에는 s=mid+1로 설정

 

 

 

3. 코드

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

public class Main {

    public static int tree_num;
    public static long need_tree;
    public static int[] tree;

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

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();

        StringTokenizer st = new StringTokenizer(br.readLine());


        // 입력
        tree_num = Integer.parseInt(st.nextToken());
        need_tree = Long.parseLong(st.nextToken());

        tree = new int[tree_num];

        st = new StringTokenizer(br.readLine());

        for (int x = 0; x < tree_num; x++) {
            tree[x] = Integer.parseInt(st.nextToken());
        }


        System.out.println(binarySearch());

    }

    public static int binarySearch() {
        int s = 0;
        int e = 1000000000;

        while (s < e) {
            int mid = (s + e) / 2;

            long sum = 0;

            for (int x : tree) {
                if (x > mid) {
                    sum += x - mid;
                }
            }

            if (sum >= need_tree) {
                s = mid + 1;
            } else {
                e = mid;
            }
        }

        return e - 1;
    }
}

728x90

'알고리즘' 카테고리의 다른 글

[JAVA]백준 1837번: 암호제작  (0) 2021.07.23
[JAVA]백준 11003번: 최솟값 찾기  (0) 2021.07.23
[JAVA]백준 2003번: 수들의 합  (0) 2021.07.20
[JAVA]백준 1339번: 단어 수학  (0) 2021.07.20
[JAVA]백준 2580번: 스도쿠  (0) 2021.07.20