Algorithm/Algorithm 풀이

[C++] 프로그래머스 - 입국심사 / 바이너리 트리

ellapk 2021. 5. 17. 01:03

문제 설명

n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다.

처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다. 가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다. 하지만 더 빨리 끝나는 심사대가 있으면 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.

모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.

입국심사를 기다리는 사람 수 n, 각 심사관이 한 명을 심사하는데 걸리는 시간이 담긴 배열 times가 매개변수로 주어질 때, 모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 입국심사를 기다리는 사람은 1명 이상 1,000,000,000명 이하입니다.
  • 각 심사관이 한 명을 심사하는데 걸리는 시간은 1분 이상 1,000,000,000분 이하입니다.
  • 심사관은 1명 이상 100,000명 이하입니다.

입출력 예

n times return

6 [7, 10] 28

 

사실 이분탐색 개념을 처음 듣고 공부하는거라 이번 문제는 구글링 참고 90으로 푼 것 같다.

풀이보단 공부...

 

left<right는 디폴트지만 left=min, right=max라고 두고 이때 max는 가장 오래 걸리는 시간이기 때문에

times중 가장 큰 원소 * n인 것이다.

 

 

바이너리 검색시 방법은, 미리 정렬된 데이터를 대상으로 반으로 나눠서 비교하기 때문에

가운데에 있는 데이터의 키 값이랑 비교해야 한다.

찾으려는 데이터보다 작으면 왼쪽, 크면 오른쪽으로 이동하는 방식이다. 

 

min이 max보다 커질 때까지 while문을 반복하여 찾는다.

 

 

#include <string>
#include <vector>
#include <algorithm>

typedef longlong ll;

using namespace std;

ll solution(int n, vector<int> times) {
    sort(times.begin(), times.end());
    
    
    ll right = (ll)times.back()*n; //right==max 최댓값임
    ll left = 0;
    ll mid;
    ll count=0;
    ll answer = right;
    
    while(left<=right){ 
        ll count =0;
        mid=(left+right)/2;
        
         for (int i = 0; i < times.size(); i++) {
            count += mid / times[i];
        }
        if (count < n) {
            left = mid + 1; //불가능하면 시간을 더 많이
        }
        else{
            if (mid <= answer) 
                answer = mid;
            right = mid - 1; //가능하면 시간 줄이기
        }
    }
    
    
    return answer;
}