일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- codingTest
- programmers
- ABAP CERTIFICATION
- Algorithm
- kakaoblind
- sap abap
- 분할정복
- 너비우선탐색
- datastructure
- DynamicProgramminng
- insertion
- kakao
- 자료구조
- binarysearch
- 알고리즘
- 최종합격후기
- 정렬
- 이분탐색
- 동적계획벅
- Baekjoon
- Altorithm
- SAP CERTI
- DivideandConquer
- 프로그래머스
- CJ올리브네트웍스
- sort
- ABAP NetWeaver 7.50
- SAP CERTIFICATION
- 백준
- LinkdeList
- Today
- Total
서랑의 개발 블로그
[프로그래머스/C++] 입국심사 본문
문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/43238
코딩테스트 연습 - 입국심사
n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다. 처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한
programmers.co.kr
풀이
이 문제는 이분 탐색(Binary Search)을 활용하여 푸는 문제이다. 이분 탐색을 통해 예상 답을 먼저 구하고 그 답이 진짜 답이 맞는지 체크 후 다시 다시 새로운 답을 구하면 된다.
sort(times.begin(), times.end()); // times를 오름차순으로 정렬
long long lt = times[0], rt = (long long)n * times[0], mid, num;
일단 times를 오름차순으로 정렬해준다. 굳이 정렬이 필요한 것은 아니지만 lt와 rt값 차이를 줄여주기 위해 정렬을 해줬다. lt는 올 수 있는 가장 작은 수 times[0]으로 초기화해주고 rt는 올 수 있는 큰 수 중 가장 작은 수를 넣어주었다. 여기서 주의할 점은 n과 times[0]이 둘 다 int형 이기 때문에 꼭 둘 중 하나는 long long으로 형 변환을 해줘야 한다. 그렇지 않으면 3,5,7,8번이 오답으로 나온다. (범위 실수를 많이 하는데 주의해서 봐야 할 것 같다.) mid는 lt와 rt의 중앙값, 즉 예상 답이고 num은 답을 체크해 주기 위한 변수이다.
while(lt <= rt){
mid = (lt + rt) / 2;
num = 0;
for(int i: times){
num += (mid / i);
}
if(num >= n) {
rt = mid - 1;
answer = mid;
}
else lt = mid + 1;
}
그다음 while문을 돌리면서 이분 탐색을 해준다. mid값을 구하고 num을 매번 새로 구해줘야 하기 때문에 0으로 초기화한다. num은 만약 mid가 답이라면 총 몇 사람이 심사를 받을 수 있는가를 구해서 저장해 줄 변수이다. for문을 times의 개수만큼 돌리면서 mid / i의 몫을 더해주면 mid시간만큼 심사를 받을 수 있는 사람의 최댓값이 나온다.
이 값을 가지고 탐색을 하는데 만약 num이 n보다 크거나 같다면 mid보다 더 작은 값으로도 n명의 심사를 할 수 있다는 뜻이다. 우리는 최솟값을 구해야 하기 때문에 rt를 mid - 1로 줄여서 다시 구하고 이 수가 답이 될 수도 있으므로 answer에는 mid를 넣어준다. 그리고 만약 num이 n 보다 작다면 더 큰 mid가 필요하다는 뜻이므로 lt를 mid + 1로 바꿔준다.
이렇게 while문을 돌면서 lt가 rt보다 커지면 answer에는 올 수 있는 가장 최소의 mid값이 들어가 있게 된다.
전체 코드
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
long long solution(int n, vector<int> times) {
long long answer = 0;
sort(times.begin(), times.end());
long long lt = times[0], rt = n * (long long)times[0], mid, num;
while(lt <= rt){
mid = (lt + rt) / 2;
num = 0;
for(int i: times){
num += (mid / i);
}
if(num >= n) {
rt = mid - 1;
answer = mid;
}
else lt = mid + 1;
}
return answer;
}
'코테 대비 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/C++] [1차] 캐시 (0) | 2021.08.14 |
---|---|
[프로그래머스/C++] [1차] 다트 게임 (0) | 2021.08.04 |