[프로그래머스] 17678 [1차] 셔틀버스 - JAVA

문제
https://school.programmers.co.kr/learn/courses/30/lessons/17678
문제 분석
조건
`n`대의 셔틀이 `t`분 간격으로 운행되며 각 셔틀에는 `m`명이 탈 수 있다.
셔틀은 09:00부터 운행하며 셔틀의 출발시간 전이나 정시에 도착한 사람만 탈 수 있다. 이때 '콘'이 셔틀을 탈 수 있는 가장 늦은 시간을 구하는 문제이다.
풀이방법
결국 '콘'은 무조건 마지막 셔틀을 타는 것인데, 이 셔틀의 상태에 의해 빈 좌석에 앉거나, 가장 마지막 탑승 인원보다 1분 빨리 줄을 서 타는 경우 2가지가 있다.
마지막 셔틀을 이전 셔틀을 못 탄 인원이 탑승할 수 있기 때문에 가장 먼저 줄은 선 크루부터 모든 크루를 태워야 하기 때문에 큐를 사용했다.
가장 먼저 `timetable`이 `String` 배열로 주어졌으므로 바로 정렬을 하여 셔틀 줄을 세운 뒤 단위를 `분`으로 변환하여 큐에 넣었다.
그 후 셔틀마다 빈자리가 있는지, `Queue`가 비어있진 않은지, 셔틀을 탈 수 있는지 확인하였으며 셔틀을 탈 때마다 셔틀 탄 시간을 업데이트했다.
마지막 셔틀버스에선 셔틀의 빈 좌석이 없으면 마지막 탑승시간보다 1분 빠르게 정답을 출력하였고, 빈 좌석이 있으면 마지막 셔틀의 출발 시간으로 출력하였다.
코드
import java.util.*;
class Solution {
public String solution(int n, int t, int m, String[] timetable) {
int answer = 0;
Arrays.sort(timetable);
Queue<Integer> que = new ArrayDeque<>();
for (String time : timetable) {
que.add(Integer.parseInt(time.substring(0, 2)) * 60 + Integer.parseInt(time.substring(3, 5)));
}
int nowShuttleTime = 9 * 60; // 09:00을 분으로 표현
int lastCrewTime = 0; // 마지막 크루 탑승시간
for (int shuttle = 1; shuttle <= n; shuttle++) {
int count = 0;
// 탑승할 자리 있고, 대기 줄 있으며 지금 셔틀 탈수있음
while (count < m && !que.isEmpty() && que.peek() <= nowShuttleTime) {
count++;
lastCrewTime = que.poll(); // 셔틀 탄 사람의 시간 기록
}
// 마지막 셔틀 버스
if (shuttle == n) {
if (count == m) { // 남은 자리 없음
answer = lastCrewTime - 1;
} else {
answer = nowShuttleTime;
}
}
nowShuttleTime += t; // 다음 셔틀 시간으로
}
return generateAnswer(answer);
}
private String generateAnswer(int answer) {
int hour = answer / 60;
int minute = answer % 60;
return String.format("%02d", hour) + ":" + String.format("%02d", minute);
}
}
주절주절
문제를 2번 풀었는데 처음엔 Time클래스를 정의하여 문제를 풀었었다.
class Time {
int hour;
int minute;
public Time(int hour, int minute) {
this.hour = hour;
this.minute = minute;
}
public void setTime(int t) {
int temp = minute + t;
if (temp < 60) {
minute = temp;
} else {
hour++;
minute = temp - 60;
}
}
}
이런 식으로 클래스를 정의하고 풀었는데 시간을 분으로 통일하여 계산하는 방법이 계산이나 비교 과정에서 매우 간결해짐을 배웠다. 자주 써먹어야지.