💻 프로그래밍/알고리즘

카카오 1차 온라인 코딩테스트 4번 문제(17.09.16)

피트웨어 제이 (FitwareJay) 2017. 10. 8. 20:59

안녕하세요 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 사이의 값이 될 수 있다.

입출력 예제

ntmtimetableanswer
115[“08:00”, “08:01”, “08:02”, “08:03”]“09:00”
2102[“09:10”, “09:09”, “08:00”]“09:09”
212[“09:00”, “09:00”, “09:00”, “09:00”]“08:59”
115[“00:01”, “00:01”, “00:01”, “00:01”, “00:01”]“00:00”
111[“23:59”]“09:00”
106045[“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(115, testTimeTable) << endl;
    cout << "con time : " << solution(2102, testTimeTable2) << endl;
    cout << "con time : " << solution(212, testTimeTable3) << endl;
    cout << "con time : " << solution(115, testTimeTable4) << endl;
    cout << "con time : " << solution(111, testTimeTable5) << endl;
    cout << "con time : " << solution(106045, 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 == 0break// 자리 다차면 끝
            }
        }
 
        // 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 아디오스~