문제

title: "코딩테스트 연습 - [1차] 셔틀버스"
image: "https://image.freepik.com/free-vector/landing-page-template-for-a-website_23-2147782747.jpg"
description: "카카오에서는 무료 셔틀버스를 운행하기 때문에 판교역에서 편하게 사무실로 올 수 있다. 카카오의 직원은 서로를 ‘크루’라고 부르는데, 아침마다 많은 크루들이 이 셔틀을 이용하여 출근한다."
url: "https://school.programmers.co.kr/learn/courses/30/lessons/17678"

문제 풀이

문제 접근

이 문제는 여러 대의 셔틀버스가 특정 시간 간격으로 운행되며, 각 셔틀에는 제한된 인원만 탑승할 수 있다는 조건이 주어진다. 주어진 크루들의 도착 시간에 따라 셔틀을 이용하는 방법을 계획해야 하며, 주인공인 콘이 가장 늦게 셔틀을 탈 수 있는 시간을 계산하는 문제이다.

핵심은 셔틀 도착 시간과 대기열에서 크루의 탑승 시간을 비교하여, 콘이 가장 늦게 셔틀을 탈 수 있는 시간을 구하는 것이다. 모든 크루가 도착한 시간 순서대로 줄을 서게 되므로, 이 문제는 크루의 도착 시간을 정렬한 후 각 셔틀에 크루들을 적절하게 배치하는 과정에서 답을 찾을 수 있다.

간단한 수도 코드 정리

1. 크루들의 도착 시간을 분 단위로 변환한다.
2. 변환된 시간 배열을 정렬한다.
3. 첫 번째 셔틀은 09:00에 도착하며, 이후 n회의 셔틀이 t분 간격으로 도착한다.
4. 각 셔틀 도착 시각마다 최대 m명의 크루를 태울 수 있다.
5. 마지막 셔틀에 콘이 타기 위해 가능한 가장 늦은 시간을 계산한다.
   - 마지막 셔틀에 자리가 있다면 셔틀 도착 시간에 맞춰 콘이 탈 수 있다.
   - 자리가 없다면 마지막으로 탄 크루보다 1분 먼저 콘이 도착해야 한다.
6. 콘이 탈 수 있는 가장 늦은 시간을 HH:MM 형식으로 반환한다.

풀이 코드

import java.util.*;

class Solution {
    public String solution(int n, int t, int m, String[] timetable) {
        // timetable을 분 단위로 변환
        int[] timeNum = new int[timetable.length];
        for (int i = 0; i < timetable.length; i++) {
            String[] time = timetable[i].split(":");
            timeNum[i] = Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]);
        }

        // 크루 도착 시간을 정렬
        Arrays.sort(timeNum);

        int busTime = 540; // 첫 셔틀 시간 (09:00)
        int idx = 0; // 대기열에서 크루 인덱스
        int lastTime = 0; // 콘이 탈 수 있는 가장 늦은 시간

        // 각 셔틀을 순서대로 처리
        for (int i = 0; i < n; i++) {
            int count = 0; // 셔틀에 탑승한 크루 수

            // 셔틀에 탈 수 있는 크루를 체크
            while (idx < timeNum.length && timeNum[idx] <= busTime && count < m) {
                count++;
                idx++;
            }

            // 마지막 셔틀일 때
            if (i == n - 1) {
                if (count < m) {
                    // 자리가 있으면 셔틀 도착 시간에 콘이 탑승
                    lastTime = busTime;
                } else {
                    // 자리가 없으면 마지막으로 탄 크루보다 1분 먼저 와야 함
                    lastTime = timeNum[idx - 1] - 1;
                }
            }

            // 다음 셔틀 시간 계산
            busTime += t;
        }

        // 시각을 HH:MM 형식으로 변환
        String hour = String.format("%02d", lastTime / 60);
        String minute = String.format("%02d", lastTime % 60);

        return hour + ":" + minute;
    }
}