백준 2805번, 나무자르기
백준 2805번 c++ 문제풀이
문제:
풀이:
- 벡터에 나무의 길이를 저장한다.
- 벡터를 오름차순으로 정렬한다.
- 0부터 가장 긴 나무 길이 사이에서 이분 탐색을 통해 가장 적절한 길이를 찾는다
- 가장 짧은 나무부터 이분 탐색을 하는 것이 아닌, 0부터 이분탐색을 하는 이유는 가장 짧은 나무를 잘라야할 수도 있기 때문이다.(주의 해야함)
- int형보다 숫자가 커질 수 있으므로 표현형을 long long 형을 쓰는 경우가 있다.(주의 하자!)
코드:
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
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
bool check(int input, vector<long long> v, int k){ //중간값을 전달 후, 이 값으로 잘랐을 떄 가능한지를 보는 함수
long long total = 0;
for(int i=0;i<v.size();i++){
if(v[i] <= input){
total += 0;
}else{
total += (v[i] - input);
}
}
if(total >= k){
return true;
}else{
return false;
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
vector<long long> v;
cin >> n >> m;
for(int i=0;i<n;i++){
long long input;
cin >> input;
v.push_back(input);
}
sort(v.begin(), v.end()); //정렬 한다.
int left;
int right;
left = 0;
right = v[n-1];
int result = 0;
while(left <= right){ //둘이 같아지거나 left가 더 커질 때까지 반복한다.
int mid = (left + right)/2;
if(check(mid, v, m)){//true면
result = mid; //최댓값 구하기
left = mid+1; //left를 더 늘려, 미드값을 증가시켜도 된다. 최댓값이 더 있을 수도 있기 때문이다.
}else{
right = mid-1; //right값을 줄여, 미드값 감소 시킨다. check 함수를 만족시키지 못했기 떄문이다.
}
}
cout << result;
return 0;
}
감사합니다.
This post is licensed under CC BY 4.0 by the author.