거의 알고리즘 일기장

카카오 블라인드 _ 셔틀버스 본문

알고리즘 문제풀이

카카오 블라인드 _ 셔틀버스

건우권 2020. 9. 26. 15:01

programmers.co.kr/learn/courses/30/lessons/17678

 

코딩테스트 연습 - [1차] 셔틀버스

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

programmers.co.kr


풀이방법

 

1. 셔틀시간 09:00 ~ 23:59

2. 콘은 최대한 가장 늦은 시간을 탐.

3. 콘은 게으르기 때문에 같은 시각에 도착한 크루 중 대기열에서 제일 뒤에 선다.

 

위의 조건을 고려해서 짜면된다. 내 로직을 간단히 설명하자면

1. 버스의 도착시간과 크루가 대기열에 선 시간을 모두 vector<시간값 ,버스도착시간이면 : 1, 크루가 대기열에 선 시간이면 : 2>형태의 자료에다가 넣는다.

2. 위의 자료를 정렬한다. 시간순서대로

3. 위의 자료를 for문 돌리면서 아래처럼 처리한다.

 3-1. 크루가 대기열에 선 시간일 경우

  대기줄에 사람하나 추가

 3-2. 버스 도착시간일 경우

  3-2-1. 마지막 버스가 아닐경우

   대기줄을 버스 허용치만큼 줄임

  3-2-2. 마지막 버스일 경우

   3-2-2-1. 버스 허용치보다 대기열이 작을 경우

    버스 시간이 답임

   3-2-2-2. 버스 허용치보다 대기열이 같거나 클 경우

    대기열에서 버스 허용치번째의 값의 -1이 답임


주의사항

1. 24:00의 값이 input에 있는듯 이 값은 무시하도록 짜야함.

2. input 값이 정렬이 안되어있음 


코드

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

int stringTimeToIntTime(string time)
{
    int hour = stoi(time.substr(0, 2).c_str());
    int minute = stoi(time.substr(3, 2).c_str());
    return hour * 60 + minute;
}

string intTimeToStringTime(int time)
{
    int hour = time / 60;
    int minute = time % 60;
    string strHour = to_string(hour);
    string strMinute = to_string(minute);

    //형식에 맞추기 위해서 
    while (1)
    {
        if (strHour.size() >= 2)
            break;
        strHour = '0' + strHour;
    }
    while (1)
    {
        if (strMinute.size() >= 2)
            break;
        strMinute = '0' + strMinute;
    }
    return strHour + ':' + strMinute;
}

bool compare(const pair<int, int>& a, const pair<int, int>& b)
{
    //시간이 같으면 버스시간이 뒤로 가야함!!
    if (a.first == b.first)
        return a.second > b.second;

    return a.first < b.first;
}

string solution(int n, int t, int m, vector<string> timetable) {
    string answer = "";

    string startTime = "09:00";
    string endTime = "23:59";
    int i_startTime = stringTimeToIntTime(startTime);
    int i_endTime = stringTimeToIntTime(endTime);

    //버스 도착시간 : 1, 크루 도착시간 : 2
    vector<pair<int, int>> updateTime;

    //1. 버스 도착시간을 updateTime에 먼저 넣는다.
    int timeOfBus = i_startTime;
    for (int i = 0; i < n; i++)
    {
        //방어코드임
        if (timeOfBus > i_endTime)
            continue;
        
        updateTime.push_back({ timeOfBus, 1 });
        timeOfBus+=t;
    }

    //2. 크루가 대기열에 선 시간을 updateTime에 먼저 넣는다.
    for (string ele : timetable)
    {
        int timeOfCrew = stringTimeToIntTime(ele);
        //방어코드임
        if (timeOfCrew > i_endTime)
            continue;

        updateTime.push_back({ timeOfCrew, 2 });
    }

    //3. 시간에 따라 정렬
    sort(begin(updateTime), end(updateTime), compare);

    //4. 이제 ㄱㄱㄱ
    queue<int> numOfPeopleInReadyPlace;
    int chance = n;
    for (int i = 0; i < updateTime.size(); i++)
    {
        //버스가 다 지나갔으면 for문을 더 돌릴 필요가 없다.
        if (chance == 0)
            break;

        int time = updateTime[i].first;
        int kind = updateTime[i].second;

        //1) 버스 도착시간일 경우
        if (kind == 1)
        {
            //chance-=1 하고 ready줄을 줄인다.
            chance -= 1;

            //마지막 버스일 경우
            if (chance == 0)
            {
                //ready줄에 인원이 아직 꽉차지 않은 경우
                if (numOfPeopleInReadyPlace.size() < m)
                {
                    answer = intTimeToStringTime(time);
                }
                //꽉찬 경우 m-1번째의 -1해준 값을 넣는다.
                else
                {
                    vector<int> temp;
                    while (1)
                    {
                        if (numOfPeopleInReadyPlace.empty())
                            break;
                        temp.push_back(numOfPeopleInReadyPlace.front());
                        numOfPeopleInReadyPlace.pop();
                    }
                    answer = intTimeToStringTime(temp[m-1]-1);
             
                }
            }

            //마지막 버스가 아닐경우
            else
            {
                //ready줄을 m만큼 줄인다.
                for (int j = 0; j < m; j++)
                {
                    if (numOfPeopleInReadyPlace.empty())
                        break;
                    numOfPeopleInReadyPlace.pop();
                }
            }
        }
        //2) 크루 도착시간일 경우
        else if (kind == 2)
        {
            //줄세우기
            numOfPeopleInReadyPlace.push(time);
        }
    }

    return answer;
}

문제 난이도가 아주높지는 않았지만.. 수고스러움이 많은 문제중 하나였다...ㅎ

반응형
Comments