공부/Code Cata

주차 요금 계산 문제

동그래님 2025. 3. 20. 11:24

📌 주차 요금 계산 문제

더보기

 

프로그래머스

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

programmers.co.kr

문제 읽다가 스크롤 압박이..;
각 차량마다 00:00 ~ 23:59 이내에 주차 되었던 모든 누적 시간을 구해서 한 번에 요금 처리를 해야되었다.
일반적으로 출차하고나서 다시 입차했을 때 기본 요금이 새로 부가되지만, 문제에서는 모든 누적 시간을 합해 한 번에 요금을 처리한다는 주의점이 있었다.
문제가 길다보니 이 부분을 놓쳐서 계산하는 로직을 수정해야했다..
그리고 또 한가지 주의할 점은 입차 기록이 있는데 출차 기록이 없는 차량은 23:59에 출차 했다고 가정하고 요금을 부여한다는 점이었다.

 

✅ 구현 코드

*전체 코드

더보기
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <sstream>
#include <iostream>

using namespace std;

int calculate_fees(const vector<int>& fees, int time)
{
    // 기본 요금
    int fee = fees[1];

    if(time > fees[0])
    {
        // 누적 시간에 따른 추가 요금
        time -= fees[0];
        (time % fees[2] == 0) ? fee += (time / fees[2]) * fees[3] : fee += (time / fees[2] + 1) * fees[3];
    }

    return fee;
}

void calculate_time(const vector<string>& records, unordered_map<string, pair<int, string>>& records_map, map<string, int>& accum_time)
{
    // 1. sstream 사용해서 records 파싱
    // 2. 각 차량번호를 key 값, 입/출차 시간과 IN/OUT을 value로 unordered_map<string, pair<int, string>에 저장
    // 3. 차량 번호마다 누적 주차 시간 계산해 map<string, int>에 저장
 
    // 차량 별 누적 시간 계산
    for (const string& record : records)
    {
        string time, car_number, io;

        stringstream ss(record);
        ss >> time >> car_number >> io;

        int hours, minutes;
        char colon;

        stringstream timestream(time);
        timestream >> hours >> colon >> minutes;
        int total_minutes = hours * 60 + minutes;

        if (records_map.find(car_number) == records_map.end())
        {
            records_map.insert({ car_number, { total_minutes, io } });
        }
        else
        {
            int prev_time = records_map[car_number].first;

            accum_time[car_number] += total_minutes - prev_time;
            records_map.erase(car_number);
        }
    }

    // 출차 기록 없는 차량, 누적 시간 추가
    if (records_map.size() > 0)
    {
        int max_minutes = 23 * 60 + 59;
        for (const auto& record : records_map)
        {
            accum_time[record.first] += (max_minutes - records_map[record.first].first);
        }
    }
}

vector<int> solution(vector<int> fees, vector<string> records)
{
    // 주차 누적 시간 정리
    unordered_map<string, pair<int, string>> records_map;
    map<string, int> accum_time;
    calculate_time(records, records_map, accum_time);
        
    //누적 시간에 따른 요금 정리
    vector<int> result;
    for (const auto& time : accum_time)
    {
        result.push_back(calculate_fees(fees, time.second));
    }

    return result;
}

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

vector<int> solution(vector<int> fees, vector<string> records)
{
    // 주차 누적 시간 정리
    unordered_map<string, pair<int, string>> records_map;
    map<string, int> accum_time;
    calculate_time(records, records_map, accum_time);
        
    //누적 시간에 따른 요금 정리
    vector<int> result;
    for (const auto& time : accum_time)
    {
        result.push_back(calculate_fees(fees, time.second));
    }

    return result;
}
  • unordered_map<string, pair<int, string>> records_map: 차량 넘버를 key 값으로 입/출차 시간 정리
  • map<string, int> accum_time: 출차 시간에서 입차 시간을 빼, 누적 주차시간 저장
  • calculate_time(): 누적 주차 시간을 구하는 메서드
  • calculate_fees(): 누적 주차 시간에 따른 요금 계산 메서드

 

🔹void calculate_time(const vector<string>& records, unordered_map<string, pair<int, string>>& records_map, map<string, int>& accum_time)

void calculate_time(const vector<string>& records, unordered_map<string, pair<int, string>>& records_map, map<string, int>& accum_time)
{
    // 1. sstream 사용해서 records 파싱
    // 2. 각 차량번호를 key 값, 입/출차 시간과 IN/OUT을 value로 unordered_map<string, pair<int, string>에 저장
    // 3. 차량 번호마다 누적 주차 시간 계산해 map<string, int>에 저장
 
    // 차량 별 누적 시간 계산
    for (const string& record : records)
    {
        string time, car_number, io;

        stringstream ss(record);
        ss >> time >> car_number >> io;

        int hours, minutes;
        char colon;

        stringstream timestream(time);
        timestream >> hours >> colon >> minutes;
        int total_minutes = hours * 60 + minutes;

        if (records_map.find(car_number) == records_map.end())
        {
            records_map.insert({ car_number, { total_minutes, io } });
        }
        else
        {
            int prev_time = records_map[car_number].first;

            accum_time[car_number] += total_minutes - prev_time;
            records_map.erase(car_number);
        }
    }

    // 출차 기록 없는 차량, 누적 시간 추가
    if (records_map.size() > 0)
    {
        int max_minutes = 23 * 60 + 59;
        for (const auto& record : records_map)
        {
            accum_time[record.first] += (max_minutes - records_map[record.first].first);
        }
    }
}
  • record를 stringstream으로 차량 번호, 입/출차 시간 등으로 파싱
  • record_map에 차량 기록이 없다면
    • record_map에 입차 기록 저장
  • record_map에 해당 차량 기록이 있다면, 이미 입차 기록이 있고 현재 출차인 것으로 판단
    • 입차 기록과 현재 출차 기록에 따른 누적 주차시간 계산
    • accum_time에 저장
  • records를 전체 순회하며 누적 시간을 계산했음에도, records_map의 기록이 남아있다면 출차 기록이 없는 차량 존재
    • 23:59에 출차 했다고 가정하고 누적 시간 계산해 accum_time에 저장

 

🔹int calculate_fees(const vector<int>& fees, int time)

int calculate_fees(const vector<int>& fees, int time)
{
    // 기본 요금
    int fee = fees[1];

    if(time > fees[0])
    {
        // 누적 시간에 따른 추가 요금
        time -= fees[0];
        (time % fees[2] == 0) ? fee += (time / fees[2]) * fees[3] : fee += (time / fees[2] + 1) * fees[3];
    }

    return fee;
}
  • 기본 요금 부여
  • 누적 주차 시간이 기본 주차 시간보다 크다면
    • 누적 주차 시간에서 기본 주차 시간을 제외
    • 남은 누적 주차 시간에 추가 요금 적용