프로그래머스, 주차요금계산

주차요금 계산문제

기본요금, 기본 시간, 단위 요금, 단위 시간이 주어지고 차량의 나가고 들어온 정보들이 주어진 후에 각 차량의 주차요금을 계산하는 문제다.

문제해결 전략

  1. split 함수를 구현해 각 차량의 입/출차 내역을 차량의 번호를 기준으로 map에 저장 (carLog)
  2. map은 중복 허용이 안되는 것을 이용해 차량이 여러번 나갔다 들어올 때를 생각해 출차가 됐으면 주차시간을 구하고 새로운 map에 저장(carAccTime)
  3. 주차 시간을 저장했으면 기존 map인 carLog에서는 해당 차의 정보를 지움 erase
  4. 마지막에 출차기록이 없는 차를 탐색하고 있다면 출차기록을 23:59로 설정 후 시간계산
  5. map은 unordered_map과 다르게 key의 오름차순 순으로 정렬되기 때문에 순서대로 요금을 계산 후 answer에 담는다.

주의할 점은 다음과 같다.

  • 출차 기록이 찍히지 않았으면 출차 시간을 23:59으로 계산
  • 요금 계산 시 math.h 헤더의 ceil함수 활용

주석으로 논리의 흐름을 잃지 않으려 애썼고, 최대한 함수를 뽑아내서 쓰려고 노력했다.

코드

#include <bits/stdc++.h>
using namespace std;

map<string, pair<string, string>> carLog; // key: 차량번호, value: {입차시간, 출차시간}
map<string, int> carAccTime; //key: 차량번호 value: 누적 시간

//문자열 자르는 함수
vector<string> split(string str, string d){
    vector<string> ret;
    long long pos = 0;
    string token = "";
    while((pos = str.find(d)) != string::npos){
        token = str.substr(0, pos);
        ret.push_back(token);
        str.erase(0, pos + d.length());
    }
    ret.push_back(str);
    return ret;
}

//입차시간과 출차시간으로 주차된 시간을 구하는 함수
int calTime(string in, string out){
    int ret;
    vector<string> v1 = split(in, ":");
    vector<string> v2 = split(out, ":");
    int inHour = stoi(v1[0]); int inMinute = stoi(v1[1]); int outHour = stoi(v2[0]); int outMinute = stoi(v2[1]);
    
    ret = (outHour*60 + outMinute) - (inHour*60 + inMinute);
    return ret;
}

//누적 시간 합을 계산
void calculate(string carNumber){
    string inTime = carLog[carNumber].first;
    string outTime = carLog[carNumber].second;
    int totalMinute = calTime(inTime, outTime); //나간시간 - 들어온시간 -> "분"으로 환산
    //차량 번호가 있을때 (이미 차량이 들어왔다 나간적이 있을때)
    if(carAccTime.find(carNumber) != carAccTime.end()){
        carAccTime[carNumber] += totalMinute;
    }
    else{
        carAccTime[carNumber] = totalMinute;
    }
}

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

    for(auto r: records){
        vector<string> log = split(r, " ");
        string time = log[0];
        string carNum = log[1];
        string dir = log[2];

        if(dir == "IN"){
            carLog[carNum].first = time;
        }
        else {
            carLog[carNum].second = time;
            // 금액 계산하고 지우기
            calculate(carNum);
            // cout<<"hi";
            carLog.erase(carNum);
        }
    }

    // 출차가 안찍혔을때 23:59로 맞추기
    for(auto& t: carLog){
        if(t.second.second.size() == 0){
            t.second.second = "23:59";
            calculate(t.first);
        }
    }

    for(auto c: carAccTime){
        int cost = 0;
        if(c.second <= fees[0]){
            cost = fees[1];
        }
        else{
            cost = fees[1] + ceil((c.second - fees[0])/float(fees[2]))*fees[3];
        }
        answer.push_back(cost);
    }
    return answer;
}

Categories:

Updated:

Leave a comment