프로그래머스, 주차요금계산
주차요금 계산문제
기본요금, 기본 시간, 단위 요금, 단위 시간이 주어지고 차량의 나가고 들어온 정보들이 주어진 후에 각 차량의 주차요금을 계산하는 문제다.
문제해결 전략
- split 함수를 구현해 각 차량의 입/출차 내역을 차량의 번호를 기준으로 map에 저장 (carLog)
- map은 중복 허용이 안되는 것을 이용해 차량이 여러번 나갔다 들어올 때를 생각해 출차가 됐으면 주차시간을 구하고 새로운 map에 저장(carAccTime)
- 주차 시간을 저장했으면 기존 map인 carLog에서는 해당 차의 정보를 지움 erase
- 마지막에 출차기록이 없는 차를 탐색하고 있다면 출차기록을 23:59로 설정 후 시간계산
- 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;
}
Leave a comment