ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 카카오 1차 온라인 코딩테스트 4번 문제(17.09.16)
    💻 프로그래밍/알고리즘 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 아디오스~

    댓글

운동하는 개발자 JAY-JI