[프로그래머스] 셔틀버스 (08.30)
문제
https://programmers.co.kr/learn/courses/30/lessons/17678
코딩테스트 연습 - [1차] 셔틀버스
10 60 45 [23:59,23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59, 23:59] 18:00
programmers.co.kr
접근법
LocalTime을 사용하여 직관적으로 풀었다.
우선 크루가 대기열에 도착하는 시간들을 우선순위 큐에 넣어서 오름차순으로 정렬하였다.
이때 테스트 케이스 중 24시가 들어오는 경우도 있으므로 24시가 들어오는 경우만 예외적으로 처리해주었다.
n번 셔틀 버스가 있으므로 for문을 n 번만큼 돌리고 그 안에서 셔틀에 탈 수 있는 최대만큼 태우는 방식을 사용하였다.
limit라는 변수에 최대 인원수를 초기화 하고
셔틀 버스를 타는 시간을 콘이 셔틀타러 나오는 시간으로 초기화 하였다.
셔틀 시간으로 초기화를 해준 이유는 셔틀이 딱 출발하는 시간에 나오면 제일 늦게 나올 수 있기 때문이다.
그 후 우선순위 큐에서 셔틀을 탈 수 있는 크루만 poll() 해준다.
이때 limit이 1인 경우를 처리해준 이유는 셔틀에 마지막 한 자리가 남았을 때 그 자리로 들어가야 제일 늦게 나올 수 있기 때문이다.
limit이 1인 경우, 즉 남은 자리가 한 자리인 경우 다음 셔틀을 탈 차례인 크루와 콘의 시간과 비교를 한다.
콘이 다음 셔틀을 탈 크루보다 시간이 늦다면 다음 셔틀을 탈 크루보다 1분 앞당겨준다.
그렇게 하면 셔틀의 마지막 남은 한 자리를 콘이 차지할 수 있게 된다.
코드
import java.time.LocalTime;
import java.util.PriorityQueue;
class Solution {
public String solution(int n, int t, int m, String[] timetable) {
PriorityQueue<LocalTime> pq = new PriorityQueue<>();
for(String time : timetable){
String[] split = time.split(":");
if(split[0].equals("24")){
split[0] = "23";
split[1] = "59";
}
pq.add(LocalTime.of(Integer.parseInt(split[0]),Integer.parseInt(split[1])));
}
//셔틀의 첫 시간은 09:00
LocalTime start = LocalTime.of(9,0);
LocalTime time = LocalTime.now();
for(int i=0;i<n;i++){
int limit = m;
time = start;
//셔틀에 크루원들을 태우고
while(!pq.isEmpty() && (pq.peek().isBefore(start) || pq.peek().equals(start)) && limit > 0){
//다음 셔틀에 탈 사람을 poll
LocalTime poll = pq.poll();
//마지막 한 자리는 콘에게
if(limit == 1){
if(time.isAfter(poll) || time.equals(poll)){
time = poll.minusMinutes(1);
}
}
limit--;
}
//다음 셔틀로
start = start.plusMinutes(t);
}
return time.toString();
}
}