카카오 1차 온라인 코딩테스트 4번 문제(17.09.16)
안녕하세요 JAY입니다~!! 오늘은 카카오 1차 온라인 코딩테스트 4번 문제를 풀어보겠습니다.
4번 문제는 조금 생각을 정리해야지 풀 수 있기 때문에 집중하시고 문제풀어 보시는게 좋습니다!!
문제 및 풀이 링크 : http://tech.kakao.com/2017/09/27/kakao-blind-recruitment-round-1/
4. 셔틀버스(난이도: 중)
카카오에서는 무료 셔틀버스를 운행하기 때문에 판교역에서 편하게 사무실로 올 수 있다. 카카오의 직원은 서로를 ‘크루’라고 부르는데, 아침마다 많은 크루들이 이 셔틀을 이용하여 출근한다.
이 문제에서는 편의를 위해 셔틀은 다음과 같은 규칙으로 운행한다고 가정하자.
- 셔틀은
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” |
- 문제 해결 방법
이 문제를 푸려면 시간계산을 정확히 해야합니다. 또한, 정리없이 무작정 풀다가는 코드가 꼬이게 되더라고요...(저만 그런가요? ㅎㅎ)
무튼, 저같은 경우는 시간계산을 쉽게 하기 위하여 string으로 입력받은 Time Table을 int형식의 분값으로 바꿨습니다.
그 다음 오름차순으로 시간을 정렬하여, 09:00시(첫차)부터 버스에 타는 크루를 체크하는 방식으로 했습니다.
정렬은 가장 쉬운 버블소트로 하였습니다.
카카오 해설을 보니 시간계산을 헷갈려서 많이 틀렸던 것 같네요. 정답률이 26.79%... (저도 풀면서 많이 헷갈렸던 것 같네요.)
이런 문제는 풀기전에 노트에 어떤식으로 문제를 풀지 정리하고 코딩을 하는게 좋은 것 같습니다.
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 104 105 106 107 108 109 | #include <iostream> #include <string> #include <vector> using namespace std; string solution(int n, int t, int m, vector<string> timetable); int StringToMintime(string time); int main(void) { string cTestTime[] = {"08:00", "08:01", "08:02", "08:03"}; string cTestTime2[] = {"09:10", "09:09", "08:00"}; string cTestTime3[] = {"09:00", "09:00", "09:00", "09:00"}; string cTestTime4[] = {"00:01", "00:01", "00:01", "00:01", "00:01"}; string cTestTime5[] = {"23:59"}; string cTestTime6[] = {"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"}; vector<string> testTimeTable(cTestTime, cTestTime + (sizeof(cTestTime) / sizeof(cTestTime[0]))); vector<string> testTimeTable2(cTestTime2, cTestTime2 + (sizeof(cTestTime2) / sizeof(cTestTime2[0]))); vector<string> testTimeTable3(cTestTime3, cTestTime3 + (sizeof(cTestTime3) / sizeof(cTestTime3[0]))); vector<string> testTimeTable4(cTestTime4, cTestTime4 + (sizeof(cTestTime4) / sizeof(cTestTime4[0]))); vector<string> testTimeTable5(cTestTime5, cTestTime5 + (sizeof(cTestTime5) / sizeof(cTestTime5[0]))); vector<string> testTimeTable6(cTestTime6, cTestTime6 + (sizeof(cTestTime6) / sizeof(cTestTime6[0]))); cout << "con time : " << solution(1, 1, 5, testTimeTable) << endl; cout << "con time : " << solution(2, 10, 2, testTimeTable2) << endl; cout << "con time : " << solution(2, 1, 2, testTimeTable3) << endl; cout << "con time : " << solution(1, 1, 5, testTimeTable4) << endl; cout << "con time : " << solution(1, 1, 1, testTimeTable5) << endl; cout << "con time : " << solution(10, 60, 45, testTimeTable6) << endl; return 0; } // string으로 받은 시각을 int형식의 분 time으로 변경(계산하기 쉽게) int StringToMintime(string time) { int minTime = 0; int hour = ((time[0] - '0') * 10 + (time[1] - '0')) * 60; int min = (time[3] - '0') * 10 + (time[4] - '0'); minTime = hour + min; return minTime; } const char timeComvertor[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; string solution(int n, int t, int m, vector<string> timetable) { string answer = ""; int shuttleFrequency = n; // 셔틀 운행 횟수 int shuttleTime = t; // 셔틀 운행 간격 int crewNumber = 0; // 셔틀타려는 크루 수 int conTime = 0; // 콘 시간 int *convertTimeTable; // string timetable -> int timetalbe convertTimeTable = new int[timetable.size() + 1]; crewNumber = timetable.size(); // 1. 분값(int)으로 string값 컨버팅 for(int i = 0; i < crewNumber; i ++) convertTimeTable[i] = StringToMintime(timetable[i]); // 2. 시간 순으로 정렬(버블소트) for(int i = 0; i < crewNumber; i ++) { int tempTime; for(int j = i; j < crewNumber - 1; j ++) { if(convertTimeTable[i] > convertTimeTable[j + 1]) { tempTime = convertTimeTable[i]; convertTimeTable[i] = convertTimeTable[j + 1]; convertTimeTable[j + 1] = tempTime; } } } int checkCrew = 0; // 버스에 탈 크루 체크(timetable 순서) int driveTime = 540; // 9 * 60 = 540분(첫차가 09시) for(int i = 0; i < shuttleFrequency; i ++) { int shuttleSeat = m; // 운행시간마다 셔틀에 탈 수 있는 최대 인원(크루) 수 // 3. 운행시각마다 셔틀타는 크루수 체크 for(int j = checkCrew; j < crewNumber; j ++) { if(convertTimeTable[j] <= driveTime) { shuttleSeat -= 1; // 인원수 빼기 checkCrew += 1; if(shuttleSeat == 0) break; // 자리 다차면 끝 } } // 4. 다음 운행이 없을 경우 콘 시간 정하기 if(i == shuttleFrequency - 1) { if(shuttleSeat == 0) conTime = convertTimeTable[checkCrew - 1] - 1; // 자리가 없을떄 else conTime = driveTime; // 자리가 있을떄 } driveTime += shuttleTime; if(driveTime >= (60 * 24)) break; } // int값을 string값으로 만들어주는 코드 int temp; temp = conTime / 60; answer += timeComvertor[temp / 10]; answer += timeComvertor[temp % 10]; answer += ":"; temp = conTime % 60; answer += timeComvertor[temp / 10]; answer += timeComvertor[temp % 10]; delete convertTimeTable; return answer; } |
오늘의 알고리즘 포스팅은 여기까지 입니다!! 즐거운 코딩하시고, 재밌는 코드 생산하세요!! :D 아디오스~