본문 바로가기

프로그래머스/Level 3

프로그래머스(Lv.3) - [1차] 셔틀버스(Java) (카카오)

 굳이 알고리즘을 나눈다고 한다면 문자열을 가지고 하는 구현 문제인 것 같다.

 

콘이 게으름을 피우기 위한 방법으로 떠오른 것은 다음과 같다.

 

1. 충분히 버스로 모든 사람을 운반할 수 있을 경우 => 제일 마지막 손님으로 나타난다.

 

2. 마지막 버스로 간당간당 다 옮길 수 있다.

Case 1. 마지막 버스가 만석이 아닐 경우 => 버스시간에 딱 맞춰온다.

Case 2. 마지막 버스가 만석일 경우 => 마지막 손님보다 딱 1분 먼저 도착한다.

 

3. 마지막 버스 타이밍에도 사람들을 다 못 옮긴다.(testcase 6) => 그냥 마지막 버스 도착시간에 도착한다.

 

이것만 명심하고 구현해 준다면, 쉽게 통과할 수 있다.

기술(?)이라고 한다면 문자열로 시간 계산은 어려우니 int로 바꾸고 시간과 분을 다른 2가지 Queue로 분할해 생각했다. Queue가 말 그대로 줄이니...

<문제>

https://school.programmers.co.kr/learn/courses/30/lessons/17678?language=java

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


<소스코드>

import java.util.*;
/*
문자열 식으로 시간이 정리 되어있으면, 시간계산에 불리할 것으로 예상
따라서 int로 바꿔서 생각하되, 시와 분은 따로 분리해서 담아두자
*/
class Solution {
    static int bus_hour = 9;
    static int bus_min = 0;
    static int conn_h = 0;
    static int conn_m = 0;
    static Queue<Integer> lane_hour;
    static Queue<Integer> lane_min;
    
    public String solution(int n, int t, int m, String[] timetable) {
        String answer = "";
        lane_hour = new LinkedList<>();
        lane_min = new LinkedList<>();
        
        Arrays.sort(timetable);
        for(int i = 0 ; i < timetable.length ; i++)
        {
            String[] temp = timetable[i].split(":");
            
            lane_hour.add(Integer.parseInt(temp[0]));
            lane_min.add(Integer.parseInt(temp[1]));
        }
        
        bus_stop(n, t, m);
        
        if(conn_h < 10) //ex) 9시라면 09시를 위한 변형
        {
            answer += ("0"+Integer.toString(conn_h));
        }
        else
        {
            answer += Integer.toString(conn_h);
        }
        answer += ":";
        if(conn_m < 10) //ex) 9분이라면 09분을 위한 변형
        {
            answer += ("0"+Integer.toString(conn_m));
        }
        else
        {
            answer += Integer.toString(conn_m);
        }
            
        
        return answer;
    }
    public static void bus_stop(int n, int t, int m)
    {
        for(int time = 0 ; time < n ; time++)
        {
            int up = 0; //탑승한 사람
            int last_h = 0;
            int last_m = 0; //마지막으로 탑승한 사람의 도착시간
            
            while(up < m && !lane_hour.isEmpty())
            {
                int hour = lane_hour.peek();
                int min = lane_min.peek();  //맨 앞사람의 시간을 비교하자!
                
                if(bus_hour > hour || (bus_hour == hour && bus_min >= min))
                {
                    //버스에 탑승
                    last_h = hour;
                    last_m = min;
                    
                    lane_hour.poll();
                    lane_min.poll();    //탔음을 의미하기 위한 줄에서 제외
                    up++;
                }
                else    //m만큼 못 채워도 뒷사람은 어차피 지금 이 사람보다 늦게 왔으니 비교대상도 아님
                    break;
            }
            
            if(time == n-1 || lane_hour.isEmpty())  //마지막 버스거나? 모든 사람이 다 탔을 때
            {
                if(up == m) //모든 정원을 태웠다면, 마지막 사람보다 1분 먼저 도착하자
                {
                    if(last_m == 0) //정각일 경우
                    {
                        conn_h = (last_h - 1);
                        conn_m = 59;
                    }
                    else    //그게 아닐 경우
                    {
                        conn_h = last_h;
                        conn_m = (last_m - 1);
                    }
                }
                else    //그게 아니라면 버스가 도착하는 시간에 도착하자
                {
                    conn_h = bus_hour;
                    conn_m = bus_min;
                }
            }
            else    //콘의 탑승시간이 안 지났다면 일단 계속 흘러가보자
            {
                bus_min += t;
                
                if(bus_min >= 60)
                {
                    bus_hour++;
                    bus_min -= 60;
                }
                
                bus_hour %= 24;
            }
        }
    }
}