[프로그래머스] [1차] 셔틀버스 / Java

2021. 3. 21. 18:59·Programmers
반응형

문제주소 :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


<문제 설명>

더보기

문제 설명

셔틀버스

카카오에서는 무료 셔틀버스를 운행하기 때문에 판교역에서 편하게 사무실로 올 수 있다. 카카오의 직원은 서로를 '크루'라고 부르는데, 아침마다 많은 크루들이 이 셔틀을 이용하여 출근한다.

이 문제에서는 편의를 위해 셔틀은 다음과 같은 규칙으로 운행한다고 가정하자.

  • 셔틀은 09:00부터 총 n회 t분 간격으로 역에 도착하며, 하나의 셔틀에는 최대 m명의 승객이 탈 수 있다.
  • 셔틀은 도착했을 때 도착한 순간에 대기열에 선 크루까지 포함해서 대기 순서대로 태우고 바로 출발한다. 예를 들어 09:00에 도착한 셔틀은 자리가 있다면 09:00에 줄을 선 크루도 탈 수 있다.

일찍 나와서 셔틀을 기다리는 것이 귀찮았던 콘은, 일주일간의 집요한 관찰 끝에 어떤 크루가 몇 시에 셔틀 대기열에 도착하는지 알아냈다. 콘이 셔틀을 타고 사무실로 갈 수 있는 도착 시각 중 제일 늦은 시각을 구하여라.

단, 콘은 게으르기 때문에 같은 시각에 도착한 크루 중 대기열에서 제일 뒤에 선다. 또한, 모든 크루는 잠을 자야 하므로 23:59에 집에 돌아간다. 따라서 어떤 크루도 다음날 셔틀을 타는 일은 없다.

입력 형식

셔틀 운행 횟수 n, 셔틀 운행 간격 t, 한 셔틀에 탈 수 있는 최대 크루 수 m, 크루가 대기열에 도착하는 시각을 모은 배열 timetable이 입력으로 주어진다.

  • 0 < n ≦ 10
  • 0 < t ≦ 60
  • 0 < m ≦ 45
  • timetable은 최소 길이 1이고 최대 길이 2000인 배열로, 하루 동안 크루가 대기열에 도착하는 시각이 HH:MM 형식으로 이루어져 있다.
  • 크루의 도착 시각 HH:MM은 00:01에서 23:59 사이이다.

출력 형식

콘이 무사히 셔틀을 타고 사무실로 갈 수 있는 제일 늦은 도착 시각을 출력한다. 도착 시각은 HH:MM 형식이며, 00:00에서 23:59 사이의 값이 될 수 있다.

입출력 예제

n                            t                            m                           timetable                 answer
1 1 5 ["08:00", "08:01", "08:02", "08:03"] "09:00"
2 10 2 ["09:10", "09:09", "08:00"] "09:09"
2 1 2 ["09:00", "09:00", "09:00", "09:00"] "08:59"
1 1 5 ["00:01", "00:01", "00:01", "00:01", "00:01"] "00:00"
1 1 1 ["23:59"] "09:00"
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"

 

<풀이법>

▒ 한줄 개념: 해시맵, 스택, 큐 ▒ 

특별한 알고리즘이 필요한 문제는 아니었다. 

n, t, m의 사이즈가 충분히 작고, 효율성 테스트 또한 존재하지 않아 기본적인 자료구조와 문자열 슬라이싱을 이용해 풀면 되는 문제이다. 물론 이 단순한 방법을 생각해내기까지 꽤나 오랜시간이 걸렸다..

 

나는 해시맵을 가장 큰 자료구조로 사용하여 풀었고, 부분적으로 큐와 스택을 사용하였다.

또한, 모든 시간문자열은 분단위를 기준으로 정수로 바꿔주었다. 이렇게 하는 편이 연산에 있어 훨씬 단순하다.

 

해시맵의 형태는 {셔틀의 출발 시간: 그 셔틀에 탈 수 있는 사람들의 도착 시간} 이다.

540부터 n, t 값을 기준으로 해시맵의 key값을 만들고, 기본 value는 모두 stack으로 만든다. 

그 이후, 정수형의 시간 값들(timetable)을 반복문을 통해서 해시맵에 삽입해주는데, 키값보다 작은 값만 채워준다. 또한, 각 해시맵의 value의 크기는 m보다 같거나 작아야한다.

1 1 5 ["08:00", "08:01", "08:02", "08:03"]

위와 같은 예시에서, 해시맵은 {540: {480, 481, 482, 483}} 의 형태를 가질 것이다.

 

2 10 2 ["09:10", "09:09", "08:00"]

위와 같은 예시에서, 해시맵은 {540: {480}, 550:{549, 550}}의 형태를 가질 것이다.

 

이런 식으로 해시맵을 다 채워주고 나면, 해시맵의 가장 큰 키값에 대한 value만 확인한다. 셔틀을 탈 수 있는 가장 마지막 시간을 정답으로 선택해야하므로, 그 앞의 시간들은 상관없다. 가장 큰 키값, 즉 가장 늦은 시간의 셔틀에 탈 수 있는 경우만 확인하면 된다.

 

따라서, 마지막 셔틀의 시간을 키값으로 둔 value 값(스택)을 확인하는데, 

1) 만약 이 stack의 사이즈가 m보다 작다면, 해당 stack에 들어갈 수 있는 가장 큰 값인 셔틀의 시간이 정답이 된다.

1 1 5 ["08:00", "08:01", "08:02", "08:03"]

위 예시가 해당 경우인데, 해시맵이 {540: {480, 481, 482, 483}}와 같다. 셔틀에 탄 사람들의 수가 m보다 작으므로, 셔틀이 출발하기 전에만 가면 이 셔틀을 탈 수 있다. 5명이 탈 수 있는 셔틀에 어차피 사람이 4명밖에 없으므로, 484분에 가던, 485분에 가던, 486분에 가던, 540분 전에만 가면 셔틀을 탈 수 있는 것이다. 따라서 가장 늦은 시간인 540분이 정답이 된다.

 

2) 만약 이 stack의 사이즈가 m과 같다면, 해당 stack에 들어있는 가장 늦게 온 사람의 시간-1 이 정답이 된다.

2 10 2 ["09:10", "09:09", "08:00"]

위 예시가 해당 경우인데, 해시맵의 형태는 {540: {480}, 550:{549, 550}}이다. 

가장 늦은 셔틀은 550분의 셔틀인데, 이는 2명(m값)이 꽉 차서 빈 자리가 없다. 따라서 마지막 탑승하는 사람보다 빨리가서 그 사람을 밀어내고 자신이 탑승해야하는 것이다. 마지막 탑승하는 사람은 550분에 탑승하러 오므로, 그보다 빠른 시간인 549분에 가면 셔틀에 탑승할 수 있고, 이 시간이 출근할 수 있는 가장 늦은 시간이 된다.

 

<코드(Java)>

import java.util.*;

class Solution {
   HashMap<Integer, Stack<Integer>> map;
    Queue<Integer> queue;
    int[] keys;
    int[] times;
    public String solution(int n, int t, int m, String[] timetable) {
        map = new HashMap<>();
        queue = new LinkedList<>();
        keys = new int[n];
        times = new int[timetable.length];
        for(int i = 0; i < times.length; i++){
            times[i] = changeTimeToInt(timetable[i]);
        }
        Arrays.sort(times);
        for(int time: times){
            queue.add(time);
        }

        for(int i = 0; i < n; i++){
            map.put(540 + t * i, new Stack<>());
            keys[i] = 540 + t * i;
        }

        int key_cnt = 0;
        while (key_cnt < n){
            if(queue.isEmpty())
                break;
            if(keys[key_cnt] >= queue.peek() && map.get(keys[key_cnt]).size() < m){
                map.get(keys[key_cnt]).push(queue.poll());
            }else{
                key_cnt++;
            }
        }

        if(map.get(keys[keys.length-1]).size() < m){
            return changeTimeToString(keys[keys.length-1]);
        }
        else{
            return changeTimeToString(map.get(keys[keys.length-1]).peek()-1);
        }
    }
    int changeTimeToInt(String time){
        return Integer.parseInt(time.substring(0,2)) * 60 + Integer.parseInt(time.substring(3,5));
    }

    String changeTimeToString(int time){
        String hours = Integer.toString(time/60);
        String minutes = Integer.toString(time%60);
        hours = hours.length() < 2 ? "0"+hours : hours;
        minutes = minutes.length() < 2 ? "0"+minutes : minutes;
        return hours+":"+minutes;
    }
}

 

 

더 많은 코드 보기(GitHub) : github.com/dwkim-97/CodingTest

 

 

반응형
저작자표시 (새창열림)

'Programmers' 카테고리의 다른 글

[프로그래머스] 외벽 점검 / Java  (3) 2021.03.22
[프로그래머스] 길 찾기 게임 / Java  (0) 2021.03.22
[프로그래머스] 단체사진 찍기 / Java  (0) 2021.03.17
[프로그래머스] 경주로 건설 / Java  (0) 2021.03.16
[프로그래머스] 자물쇠와 열쇠 / Java  (0) 2021.03.15
'Programmers' 카테고리의 다른 글
  • [프로그래머스] 외벽 점검 / Java
  • [프로그래머스] 길 찾기 게임 / Java
  • [프로그래머스] 단체사진 찍기 / Java
  • [프로그래머스] 경주로 건설 / Java
개발하는 사막여우
개발하는 사막여우
개발개발 주저리주저리
    반응형
  • 개발하는 사막여우
    개발하는 사막여우
    개발하는 사막여우
  • 전체
    오늘
    어제
    • All (311)
      • Books (13)
        • 읽기 좋은 코드가 좋은 코드다 (13)
      • Study (6)
        • Blockchain (3)
        • Algorithm (3)
      • Baekjoon (36)
      • Programmers (166)
      • LeetCode (15)
      • Open Source (1)
        • Youtube Popout Player (1)
      • Language (32)
        • Python (9)
        • JS (8)
        • Java (5)
        • HTML (6)
        • CSS (4)
      • Library & Framework (15)
        • React.js (15)
      • IDE (2)
        • IntelliJ (2)
      • Airdrop (9)
      • Tistory (2)
      • etc.. (7)
        • Cozubi (6)
        • lol-chess (0)
  • 블로그 메뉴

    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    카카오 공채
    알고리즘문제풀이
    카카오 코딩테스트
    코인줍줍
    백준
    파이썬
    클린 코드 작성법
    신규 코인 에어드랍
    코딩테스트연습
    2018 KAKAO BLIND RECRUITMENT
    읽기 좋은 코드가 좋은 코드다
    programmers
    프로그래머스
    Cozubi
    Python
    Java
    프로그래머스 위클리 챌린지
    카카오 알고리즘 문제
    코주비
    클린 코드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
개발하는 사막여우
[프로그래머스] [1차] 셔틀버스 / Java
상단으로

티스토리툴바