알고리즘/백준

[백준 2805] 나무 자르기 C++

겜도리도리 2022. 6. 22. 22:47
반응형

문제

백준 2805 나무 자르기 C++

 

2805번: 나무 자르기

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

www.acmicpc.net

풀이

전형적인 이분 탐색 문제입니다.

low = 0, high는 나무의 최대 높이로 설정한 뒤, mid 값을 바꿔가며 이분 탐색을 시행합니다.

low > high 조건을 만족하기 전의 result 값이 최종결과가 됩니다.

sum은 int 범위를 초과할 수 있으므로 long long 타입으로 설정합니다.

 

한편, N의 최대 개수가 백만이라 시간초과가 나지 않을까 걱정했지만, C++은 N = 1억일 때 1초 정도 걸린다고 한다.

그 전에는 N = 백만일 때 1초 정도 걸리는 걸로 기억하고 있었는데, 아마 $O(n^2)$이랑 헷갈리지 않았나 싶다.

소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
 
    int N, M;
    cin >> N >> M;
 
    vector<int> v;
    int height;
 
    int low = 1;
    int mid = 0;
    int high = 0;
    int result = 0;
 
    for (int i = 0; i < N; i++)
    {    
        cin >> height;
        v.push_back(height);
 
        if (height > high)
        {
            high = height;
        }
    }
 
    while (1)
    {
        if (low > high)
            break;
 
        mid = (low + high) / 2;
        long long sum = 0;
 
        for (int treeHeight : v)
        {
            int cutHeight = treeHeight - mid;
 
            if (cutHeight > 0)
            {
                sum += cutHeight;
            }
        }
 
        // 목표치 달성
        if (sum >= M)
        {
            result = mid;
            low = mid + 1;
        }
        // 목표치 미달성
        else
        {
            high = mid - 1;
        }
    }
 
    cout << result;
    return 0;
}
cs
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 14890] 경사로 C++  (0) 2022.07.04
[백준 2343] 기타 레슨 C++  (0) 2022.06.26
[백준 2667] 단지번호붙이기 C++  (0) 2022.06.01
[백준 1260] DFS와 BFS C++  (0) 2022.05.31
[백준 15654] N과 M (5) C++  (0) 2022.05.02