본문 바로가기

Algorithm

[2022KAKAO BLIND RECRUITMENT]주차 요금 계산

https://school.programmers.co.kr/learn/courses/30/lessons/92341

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

2022 KAKAO BLIND RECRUITMENT 주차 요금 계산 문제입니다

 

해당 문제는 차량의 입 출 기록과 요금기준을 바탕으로 쳐라마다의 주차 요금을 계산하는 문제입니다

 

문제의 이해

입출 기록은 [들어온시간, 차량번호, 입출타입]의 방식으로 vector에 담겨서 주어집니다

또한 요금 기준은[기본시간, 기본요금, 단위시간, 단위요금]의 방식으로 담겨서 주어집니다

예를 들어 00:00에 차량이 들어오고 12:00에 차량이 나갔다면

해당 차량은 12시간 만큼의 요금을 지불해야 하는 문제입니다

 

 

문제의 접근

이문제의 포인트는

1. 어떻게 차량의 주차시간을 정리할것인가

2. 정리된 주차시간을 토대로 차량의 요금을 어떻게 계산할 것인가

이 두 가지가 문제의 중요 포인트입니다

우선 차량의 주차시간을 정리하는 방법은 저는 map을 활용해서 차량의 입출 데이터를 쌓았습니다

사실 3번째 인자인 IN OUT 정보는 크게 상관이 없습니다

왜냐하면 들어와야 나갈 것이고 들어오지 않았다면 나가는 데이터가 존재할 수가 없습니다 때문에 우리는

이미 시간 순서대로 정리된 데이터를 기반으로 [차량 번호], [시간, 시간, 시간...] 이러한 방식으로 데이터를 쌓아주기만 한다면 시간의 첫 번째 값은 들어온 시간이 될 것이고 두 번째 값은 나간 시간이 될 것입니다.

이렇게 정리된 값을 바탕으로  [두 번째 시간- 첫 번째 시간]을 계산해서 차량의 주차 한 시간들을 더해줌으로써 주차시간을 구하면 됩니다

 

다음으로 요금 계산입니다

계산 방식은 간단합니다

기본시간 + (주차시간 - 기본시간)/단위시간 * 단위요금 이 기본적인 계산 방식이 될 것입니다

물론 기본시간 이하로 차량이 주차를 했다면 기본요금만 내면 됩니다 또한 (/단위시간)은 올림으로 계산됩니다

 

풀이

1. 주차시간 정리

우선 map을 사용해서 map <string, vector <int>>에 [차량번호][시간, 시간, 시간]의 방식으로 데이터를 쌓아나갈 것입니다

이 과정에서 문자열을 각각의 문자열 사이에 띄어쓰기와 시:분 사이에 ':'를 활용해서 분 단위로 시간을 저장할 예정입니다

추후에 요금계산의 편의성을 위해 미리 정리해서 두는 게 편합니다

저는 IN, OUT 정보가 필요 없기 때문에 count 변수를 하나 생성해서 3번째 in, out 정보는 흘리도록 했습니다

 

2. 요금계산

위의 정리된 데이터를 토대로 요금을 계산합니다

짝수번째 시간 - 홀수 번째 시간 + 짝수번째시간 +홀수 번째 시간... 이런 식으로 계산을 이어나갈 예정입니다

이때 들어온 차량이 나간 시간이 없는 경우가 있습니다 이경우 저는 24:00 - 들어온 마지막 시간을 합해줄 것입니다

마지막으로 올림연산 하나 집고 가겠습니다 평소에 ceil함수를 사용해서 올림연산을 했었는데 이번에 알아보다가 

빠른 올림연산을 찾았습니다 (x+y-1)/y 이렇게 하면 빠른 올림연산이 된다고 합니다 해당연산과 삼항연산자로 마지막 요금을 계산하며 요금계산을 마쳤습니다

 

 

#include <string>
#include <vector>
#include <map>
#include <sstream> 
#include <iostream>

using namespace std;

vector<int> solution(vector<int> fees, vector<string> records) {

    map<string, vector<int>> book;
    vector<int> answer;
    string ss;

    for (string s : records)                                         // 주차 시간 정리
    {
        int count = 0;                                              // records에있는 2번째 값 까지만 쓸것이기때문에 생성한 변수
        int time = 0;                                               // 입출시간
        string key = "";                                            // 차량 번호 
        stringstream stream(s);
        while (stream >> ss)
        {
            if (count < 2)
            {
                if (count == 0)
                {
                    int prev = 0;
                    int cur;
                    cur = ss.find(':');
                    while (cur != string::npos)
                    {
                        string substring = ss.substr(prev, cur - prev);
                        time += stoi(substring) * 60;                       // 시간 -> 분단위로 정리함
                        prev = cur + 1;
                        cur = ss.find(':', prev);
                    }
                    time += stoi(ss.substr(prev, cur - prev));              // 남은 분 처리
                }
                if (count == 1)
                {
                    key = ss;
                }
                count++;
            }
            else
            {
                book[key].push_back(time);
            }
        }
    }

    for (auto p : book)                                                     // 요금 계산
    {
        vector<int> compare;
        int totaltime = 0;
        for (int i = 0; i < p.second.size(); i++)
        {
            if (i % 2 == 0)
            {
                compare.push_back(p.second[i]);
            }
            else
            {
                totaltime += p.second[i] - compare[0];
                compare.clear();
            }
            if (((p.second.size() - 1) == i) && !(compare.empty()))
            {
                totaltime += 1439 - compare[0];
            }
        }
        int totalprice = totaltime - fees[0] > 0 ? (totaltime - fees[0] + fees[2] - 1) / fees[2] * fees[3] + fees[1] : fees[1];
        answer.push_back(totalprice);
    }

    return answer;
}

 

후기

kakao 2단계 문제는 문자열 다루는 문제가 항상 나오는 느낌인 거 같습니다 뭔가 현실적인 문자열문제라 항상 풀면서 재미있었던 거 같습니다 난이도는 무난했던 거 같고 빠른 올림연산을 찾았던 게 조금 기분 좋았던 문제였습니다