https://programmers.co.kr/learn/courses/30/lessons/43238
코딩테스트 연습 - 입국심사
n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다. 처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한
programmers.co.kr
[문제 설명]
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 |
입출력 예 설명
가장 첫 두 사람은 바로 심사를 받으러 갑니다.
7분이 되었을 때, 첫 번째 심사대가 비고 3번째 사람이 심사를 받습니다.
10분이 되었을 때, 두 번째 심사대가 비고 4번째 사람이 심사를 받습니다.
14분이 되었을 때, 첫 번째 심사대가 비고 5번째 사람이 심사를 받습니다.
20분이 되었을 때, 두 번째 심사대가 비지만 6번째 사람이 그곳에서 심사를 받지 않고 1분을 더 기다린 후에 첫 번째 심사대에서 심사를 받으면 28분에 모든 사람의 심사가 끝납니다.
[문제 분석]
이분탐색을 이용하여 문제를 해결하라고 하는데 어느 부분을 이분탐색 해야할 지 파악하는 것이 힘들었다.
주어진 시간동안 심사할 수 있는 사람 수를 이분탐색하면 되는 문제였다.
변수 long sum은 해당 시간에 입국 심사할 수 있는 사람 수를 의미한다.
start=0, end=Long.MAXVALUE부터 시작한다. 주어진 시간은 mid 변수로, start와 end합의 절반이다. (mid = (start+end)/2;)
입국 심사를 마치는데 걸리는 최솟값을 찾아야하므로 answer는 가장 큰 값인 Long.MAXVALUE로 초기화한다.
start가 end보다 작거나 같을 때까지 반복문을 수행할 것인데, 반복문 내에서 해야 할 작업은 다음과 같다.
1. sum을 0으로 초기화, mid = (start+end)/2로 초기화 한다.
2. times 배열의 크기만큼 반복문 수행, 해당 반복문 내에서는 sum값을 계산할 것이다. sum은 times배열의 각 값으로 mid 값을 나눈 몫을 다 더해주면 된다. 반복문 수행 도중 sum값이 n보다 크다면, 해당 시간 내에 입국 심사할 수 있는 사람의 수가 주어진 입국 심사를 기다리는 사람 수 보다 많으므로 반복문을 멈춘다.
3. 반복문 도중 종료하든, 반복문이 times배열 끝까지 돌든, 해당 반복문이 종료되면 sum값을 n값과 비교한다.
3-1. 만약 sum>=n이면, 해당 시간에 입국심사할 수 있는 사람 수가 입국 심사를 기다리는 사람 수 보다 많다는 것이므로, 즉 시간이 넘친다는 것을 의미한다. 따라서 end를 mid-1로 조정해준다. 그리고 answer는 모든 사람이 심사 받는데 걸리는 시간 중 최솟값을 의미할 것이므로, 현재 answer값보다 mid 값이 작다면, answer를 mid값으로 변경해준다.
3-2. 만약 sum<n이면, 해당 시간에 입국 심사할 수 있는 사람 수가 입국 심사를 기다리는 사람 수 보다 적다는 것이므로, 즉, 시간이 부족하다는 것을 의미한다. 따라서 start를 mid+1로 조정해준다.
[코드]
import java.util.*;
class Solution {
public long solution(int n, int[] times) {
Arrays.sort(times);
long start =0, end=Long.MAX_VALUE, mid;
long answer = end;
long sum=0;
while(start<=end){
sum=0;
mid = (start+end)/2;
for(int i=0;i<times.length;i++){
sum+=mid/times[i];
if(sum>n)
break;
}
if(sum>=n){
if(answer>mid)
answer=mid;
end=mid-1;
}
else{
start=mid+1;
}
}
return answer;
}
}
'Algorithm > 프로그래머스' 카테고리의 다른 글
프로그래머스_키패드 누르기(JAVA) (0) | 2021.08.07 |
---|---|
프로그래머스_정수 삼각형(JAVA) (0) | 2021.08.04 |
프로그래머스_N으로 표현(JAVA) (0) | 2021.08.03 |
프로그래머스_다리를 지나는 트럭(JAVA) (0) | 2021.08.01 |
프로그래머스_모의고사(JAVA) (0) | 2021.08.01 |