백준 2805 - 나무 자르기 - 이분 탐색

Byungwoong An·2021년 6월 10일
0

문제


문제링크 : https://www.acmicpc.net/problem/2805

풀이전략

  1. 나무를 몇미터에서 자를지가 중요하다. 하지만 나무의 개수는 1000000으로 N^2으로 해결하면 문제를 풀 수 없다. 따라서 NlogN으로 만들기 위해 이분 탐색을 사용한다.
  2. M은 2,000,000,000 이고 N은 1,000,000이다. 따라서 int형으로는 나무의 높이의 합을 계산할 때 부족할 수 있다. 따라서 long long을 사용해주어야한다.
  3. 먼저 높이를 선정하고, 그 높이로 나무들로부터 총 얼마를 얻을 수 있나를 계산한다. 나무들로부터 얻을 수 있는 값이 목표치보다 작을 경우 자를 높이를 낮춰주고 그 반대의 경우 자를 높이를 높여주면 된다.

코드

#include<bits/stdc++.h>

using namespace std;

// 틀린이유 1 long long 으로 선언해주는 것을 생각하지 못함

int N, M;
vector<int> arr;
int res;
int resVal = 2147000000;
long long getSum(int num){
    long long sum = 0;
    for(int i=1; i<=N; i++){
        if(arr[i] > num){
            sum += arr[i]-num;
        }
    }
    return sum;
}

int BinarySearch(int lt, int rt){
    if(lt>rt){
        return res;
    }
    else{
        int mid = (lt+rt) / 2;
        long long ret = getSum(mid);
        if(ret == M){
            return mid;
        }
        else if(ret > M){
            if(resVal > ret){
                res = mid;
            }
            return BinarySearch(mid+1, rt);
        }
        else{
            return BinarySearch(lt, mid-1);
        }
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    freopen("../input.txt","rt",stdin);
    cin >> N >> M;
    int tmp;
    arr.push_back(0);
    for(int i=1; i<=N; i++){
        cin >> tmp;
        arr.push_back(tmp);
        
    }
    sort(arr.begin(), arr.end());
    /// 두번째 틀린이유 아무생각없이 arr[1]을 넣었음 모든 나무의 크기도 같을수 있음을 생각했어야한다. 
    cout<<BinarySearch(1, arr[N])<<endl;
    // cout<<BinarySearch(arr[1], arr[N])<<endl;
    return 0;
}


소감

문제를 한번에 풀지 못하였는데 그 이유는 먼저 long long으로 값을 선언해 주지 않아서이다. 또한 모든 나무도 같은 값을 가질 수 있으므로 아무생각없이 가장 작은 값을 lt로 넣어주는 것이 아니라 1을 넣어주어야한다.

반드시 int형을 벗어나면 long long으로 선언해주어야한다.

profile
No Pain No Gain

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN