프로그래머스의 입국심사(Lv3) 문제이다.
[ 문제풀이 ]
모든 경우의 수를 다 탐색해 보기에는 사람의 수도, 걸리는 시간도, 심사관의 수도 너무나도 값들이 크다.
그래서 이분탐색을 이용해서 탐색해 주었다.
탐색의 조건은 "시간이 T분 주어졌을 때, 주어진 n명이 모두 심사받을 수 있는지?" 이다. 즉 ! 시간을 크게도 만들어보고 작게도 만들어보면서, n명이 모두 심사받을 수 있는 최소의 시간을 찾는 것이다.
그럼 T분이 주어졌을 때, 각 심사대가 몇 명을 심사할 수 있는지부터 알아보자.
예를 들어서 심사대가 딱 1개가 있고, 이 심사대는 심사하는데 5분이 걸린다고 가정해보자.
그리고 주어진 시간이 10분이라고 가정해보자. 몇 명을 심사할 수 있을까 ?? 2명이다. 너무나도 쉬운 계산이다.
그럼 주어진 시간이 12분이라고 가정해보자. 몇 명을 심사할 수 있을까 ?? 2명이다. 어떻게 계산했는지는 모르겠지만 2명인 건 알 것 같다.
그럼 주어진 시간이 T분이라고 가정해보자. 몇 명을 심사할 수 있을까 ??
바로 "T / 5" 명이 된다. 하나 더 나아가보자. 심사대가 심사하는데 걸리는 시간이 x분이 걸린다. 그리고 T분이 주어졌을 때,
이 심사대에서는 주어진 시간동안 몇 명을 심사할 수 있을까 ?
심사 받을 수 있는 사람의 수 = T / x 명 !
이렇게 계산할 수가 있다.
하나만 더 나아가보자. 심사대가 3개가 있다. 각 심사대는 심사하는데 { a, b, c } 분이 걸린다고 가정하자.
그리고 시간이 T분이 주어졌다. 총 몇 명이 심사를 받을 수 있을까 ??
심사를 받을 수 있는 사람의 수 = T / a + T / b + T / c
위와 같이 계산을 할 수가 있다.
즉 ! 우리는 위와 같이 시간 T의 값을 이분탐색으로 탐색해보면서, 구체적으로는 "T분이 주어졌을 때, 심사를 받을 수 있는 사람의 수가 n명 이상인가?" 를 판단할 것이다.
그럼 이분탐색을 위해서는 초기 Start값과 End값(Left & Right값) 이 필요하다.
어떻게 설정해줄까 ?? 우리의 기준은 "시간" 이다.
Start의 값은 1분으로 설정해주자.
그럼 End의 값은 ?? 문제에 주어진 시간의 최댓값인 1000000000 분으로 설정해도 무관하지만 본인은 "주어진 입력에서 걸릴 수 있는 최대시간" 을 End 값으로 설정해 주었다.
예를 들어서 심사대가 3개가 있고, 각각의 심사대는 심사하는데 { 1, 2, 3 } 분이 걸린다고 가정해보자.
그리고 사람 10명이 심사를 받아야 하는 상황이다. 최악의 경우, 즉 심사를 하는데 가장 오랜 시간이 걸리게 심사를 받게 만들려고 한다면 몇 분이 걸릴까 ??
10명 모두 3분이 걸리는 심사대에서만 심사를 받게하면 가장 오랜시간이 걸리게 만들 수 있다.
즉 ! 3 x 10 = 30분이 위의 케이스에서 심사를 하는데 가장 오래 걸릴 수 있는 최대시간 이 된다.
위와 같이, 주어진 입력에서 "심사하는데 가장 오래걸리는 심사대의 시간 x 사람의 수" 를 End 값으로 설정해 주었다.
이 후, 이분탐색에서는 위에서 이야기했던 "심사를 받을 수 있는 사람의 수"를 계산하면서 정답을 찾아주었다.
[ 소스코드 ]
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 | #include <string> #include <vector> using namespace std; long long Binary_Search(long long Mid, vector<int> T) { long long Result = 0; for (int i = 0; i < T.size(); i++) { Result = Result + (Mid / T[i]); } return Result; } long long solution(int n, vector<int> times) { long long Start = 1; long long End = 0; long long Temp = 0; for (int i = 0; i < times.size(); i++) { if (Temp < times[i]) Temp = times[i]; } End = Temp * n; while(Start <= End) { long long Mid = (Start + End) / 2; if (Binary_Search(Mid, times) < n) Start = Mid + 1; else End = Mid - 1; } return Start; } | cs |
'[ Programmers Code ] > # PG - Level3' 카테고리의 다른 글
[ 프로그래머스 이중 우선순위 큐 (Lv3) ] (C++) (0) | 2020.08.11 |
---|---|
[ 프로그래머스 여행 경로 (Lv3) ] (C++) (16) | 2020.08.11 |
[ 프로그래머스 단속카메라 (Lv3) ] (C++) (0) | 2020.08.06 |
[ 프로그래머스 단어 변환 (Lv3) ] (C++) (12) | 2020.07.30 |
[ 프로그래머스 가장 먼 노드 (Lv3) ] (C++) (0) | 2020.07.23 |