카카오 신입공채 1차 코딩테스트 문제4 셔틀버스 JAVA 예제
- JAVA/알고리즘과 자료구조
- 2018. 4. 5. 22:11
카카오톡 신입공채 1차 코딩 테스트 문제4 셔틀버스 JAVA 예제
카카오 신입공채 1차 코딩테스트 문제4 셔틀버스 JAVA 예제
문제설명
카카오에서는 무료 셔틀버스를 운행하기 때문에 판교역에서 편하게 사무실로 올 수 있다. 카카오의 직원은 서로를 ‘크루’라고 부르는데, 아침마다 많은 크루들이 이 셔틀을 이용하여 출근한다.
이 문제에서는 편의를 위해 셔틀은 다음과 같은 규칙으로 운행한다고 가정하자.
- 셔틀은 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 사이이다.
출력형식
입출력 예제
문제해설
쉬워 보이는데 어려운 문제가 바로 이 문제였던 거 같네요. 당초 난이도를 ‘중’으로 두고 문제를 중간 즈음에 배치하였는데, 시간을 계산하는 부분에서 많은 분들이 어려워하셨던 거 같습니다.
예를 들어 2번 입출력 예제의 경우 ["09:10", "09:09", "08:00"]인데 이 경우 두 번째 버스는 9:10분에 출발하기 때문에 9:10분에 오면 되지 않느냐 많이들 혼동하셨을 거 같아요. 하지만 9:00에 오는 버스는 8:00에 대기하는 크루 1명만 탑승할 수 있고, 따라서 9:10 버스에는 남아 있는 두 명이 모두 타게 됩니다. 따라서 좀 더 이른 9:09에 와야 탑승할 수 있습니다.
전체 계산은 어렵지 않지만 이처럼 정확하게 시간 계산을 해야 하는 부분이 많고 마지막 버스 시간까지 빈틈없이 계산해야 해서 많은 분들이 실수를 한 거 같습니다. 이 문제는 정답률이 두 번째로 낮은 26.79%입니다.
문제출처 : http://tech.kakao.com/2017/09/27/kakao-blind-recruitment-round-1/
JAVA 예제
솔직히 말해서 개인적으로 이번 문제가 제일 어려웠습니다. 어떻게 억지로 풀기야 풀었지만, 깔끔하지 못해서 마음에 들지 않습니다. 로직도 if, else가 너무 많이 들어갔고, 시간 계산 때문에 "시:분"에 대한 단위 환산 처리까지 함께 고려하느라 논리적으로 로직이 깔끔한 모습은 아니였습니다. 조금더 고민하고 정갈하게 소스를 짤 수 있도록 더 노력해야 겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import java.util.Arrays; public class Bus { public static void main(String[] args) { System.out.println(getLastTime(1, 1, 5, new String[]{"08:00", "08:01", "08:02", "08:03"})); System.out.println(getLastTime(2, 10, 2, new String[]{"09:10", "09:09", "08:00"})); System.out.println(getLastTime(2, 1, 2, new String[]{"09:00", "09:00", "09:00", "09:00"})); System.out.println(getLastTime(1, 1, 5, new String[]{"00:01", "00:01", "00:01", "00:01", "00:01"})); System.out.println(getLastTime(1, 1, 1, new String[]{"23:59"})); System.out.println(getLastTime(10, 60, 45, new String[]{"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"})); } /** * 마지막으로 탈 수 있는 버스 시간 추출 * @param n 금일 버스운행 횟수 * @param t 버스운행 간격 * @param m 한번에 태울 수 있는 사람 수 * @param waitTime 줄서고 있는 사람들 * @return 마지막으로 탈 수 있는 버스 시각 */ public static String getLastTime(int n, int t, int m, String[] waitTime) { String answer = ""; // 버스 도착시간 계산 String[] busTime = new String[n]; for(int i = 0; i < n ; i++) { busTime[i] = getAddTime("09:00", t*i); } String lastBustTime = busTime[n-1]; //대기자 명단을 먼저온 기준으로 정렬 Arrays.sort(waitTime); int curPos = 0; int curAdded = 0; String busStop = ""; for(int j = 0; j < busTime.length; j++) { busStop = busTime[j]; curAdded = 0; // 순차적으로 버스가 들어옴을 for로 처리 for(int k = curPos ; curPos < waitTime.length; k++) { // 현재 버스에 시간 이전에 도착한 사람이 있는 경우 && 현재 버스에 빈 자리가 있는 경우 if(getMinLong(busStop)>=getMinLong(waitTime[k]) && curAdded < m ) { answer = waitTime[curPos]; // 마지막 탑승 가능한 사람 도착 시간 입시저장 answer = getAddTime(answer, -1); // 마지막 탑승 가능자 보다 1분 빨리 오도록 임시시간 지정 curPos++; curAdded++; // curAdd < m 버스 자리가 여유있고, 마지막 탑승객이면 현재 버스 시간에 맞게 나감 if(j==busTime.length -1 && k == waitTime.length-1 && curAdded < m) { answer = busTime[n-1]; } } else { // 마지막 버스 인데 탑승객이 전부 못타는 경우 최종탑승자(answer)보다 빨리 와야 함 if(j==busTime.length-1 && curPos >= 1) { // 마지막 탑승 가능한 사람 도착 시간 입시저장 answer = waitTime[curPos -1]; answer = getAddTime(answer, -1); } break; } } } // 마지막 버스를 타도 여유가 있는 경우 if("".equals(answer)||getMinLong(answer) > getMinLong(lastBustTime)) { answer = lastBustTime; } return answer; } /** * hh:mm의 String을 입력받아 addMin만큼 더한 시간 리턴 * @param hhmm * @param addMin * @return hhmm분에 addMin분 을 합산한 시간 */ private static String getAddTime(String hhmm, int addMin) { long temp = getMinLong(hhmm); temp = temp + addMin; int hh = (int)temp/60; int mm = (int)temp%60; return String.format("%02d", hh)+":"+String.format("%02d", mm); } /** * hh:mm 의 스트링을 입력받아 long형태의 분으로 리턴 * 입력 String 01:30, 출력 long 90 * @param hhmm * @return long타입의 분 */ private static long getMinLong(String hhmm) { String arr[] = hhmm.split(":"); int hh = Integer.parseInt(arr[0]); int mm = Integer.parseInt(arr[1]); return hh*60+mm; } } | cs |
문의 및 댓글 환영 :)
'JAVA > 알고리즘과 자료구조' 카테고리의 다른 글
카카오 신입공채 1차 코딩테스트 문제6 프렌즈블록 JAVA 예제 (0) | 2018.04.05 |
---|---|
카카오 신입공채 1차 코딩테스트 문제5 뉴스클러스터링 JAVA 예제 (1) | 2018.04.05 |
카카오 신입공채 1차 코딩테스트 문제3 캐시 JAVA 예제 (4) | 2018.04.05 |
카카오 신입공채 1차 코딩테스트 문제2 다트게임 JAVA 예제 (1) | 2018.04.05 |
카카오 신입공채 1차 코딩테스트 문제1 비밀지도 JAVA 예제 (5) | 2018.04.05 |
이 글을 공유하기