문제 : 프로그래머스 주차 요금 계산 🚘
난이도 : LEVEL 2
조건 1️⃣ 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주한다.
조건 2️⃣ 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산한다.
조건 3️⃣ 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담는다.
☝️ 요금표 (주차 요금을 나타내는 정수 배열 fees)
✌️ 입/출차 기록 (자동차의 입/출차 내역을 나타내는 문자열 배열 records
과정 1️⃣ 차량별로 주차 요금을 계산해야 하므로 차량별로 입/출차 기록을 저장한다.
차량 번호 5961의 입/출차 기록 : [05:34, 입차], [07:59, 출차], [22:59, 입차], [23:00, 출차]
차량 번호 0000의 입/출차 기록 : [06:00, 입차], [06:34, 출차], [18:59, 입차]
차량 번호 0148의 입/출차 기록 : [07:59, 입차], [19:09, 출차]
과정 2️⃣ 차량별로 누적 주차 시간(출차-입차 시간의 합)을 구한다.
1) 차량 번호 5961의 입/출차 기록 : [05:34, 입차], [07:59, 출차], [22:59, 입차], [23:00, 출차]
첫 번째 주차 시간은 [07:59, 출차] - [05:34, 입차] = [02:25]
두 번째 주차 시간은 [23:00, 출차] - [22:59, 입차] = [00:01]
➡️ 누적 주차 시간 = [02:25] + [00:01] = 2:26 = 60x2+26 = 120 + 26 = 146분
2) 차량 번호 0000의 입/출차 기록 : [06:00, 입차], [06:34, 출차], [18:59, 입차]
첫 번째 주차 시간은 [06:34, 출차] - [06:00, 입차] = [00:34]
남은 시간은 [18:59, 입차] 이다.
☝️이때, 입차 시간은 있지만, 출차 시간이 더이상 없다!!
따라서 이러한 경우 23:59에 출차된 것으로 간주한다.
두 번째 주차 시간은 [23:59] – [18:59] = [05:00]
➡️ 누적 주차 시간 = [00:34] + [05:00] = 5:34 = 60 x 5+34 = 300 + 34 = 334분
3) 차량 번호 0148의 입/출차 기록 : [07:59, 입차], [19:09, 출차]
첫 번째 주차 시간은 [19:09, 출차] - [07:59, 입차] = [11:10]
➡️ 누적 주차 시간 = [11:10] = 60x11 + 10 = 660 + 10 = 670분
과정 3️⃣ 차량별로 누적 시간을 바탕으로 주차 요금 계산한다.
1) 차량 번호 5961의 주차 요금
누적 주차 시간 = 146분 < 기본 시간 = 180분 ➡️ 기본 요금 = 5000원
2) 차량 번호 0000의 주차 요금
누적 주차 시간 = 334분 > 기본 시간 = 180분
➡️ 초과 시간 = 334분 – 180분 = 154분
➡️ 초과 요금 = (154분 / 10분) x 600원 = 16 x 600원
= 9600원 + 기본 요금 (5000원) = 14600원
3) 차량 번호 0148의 주차 요금
누적 주차 시간 = 670분 > 기본 시간 = 180분
➡️ 초과 시간 = 670분 – 180분 = 490분
➡️ 초과 요금 = (490분 / 10분) x 600원 = 49 x 600원
= 29400원 + 기본 요금(5000원) = 34400원
이때, 차량 번호를 오름차순으로 정렬한다.
따라서 [차량 번호, 주차 요금] = [0000, 14600], [0148, 34400], [5961, 5000]
#include <string>
#include <vector>
#include <sstream>
#include <map>
#include <set>
using namespace std;
//차량별로 누적 시간을 바탕으로 주차 요금 계산한다.
int park_fees(vector<int> fees, int park_times){
if(fees[0] > park_times){
return fees[1];
}
else if(((park_times-fees[0])%fees[2]) != 0){
return fees[1] + ((park_times-fees[0])/fees[2]+1) * fees[3];
}
else{
return fees[1] + (park_times-fees[0])/fees[2] * fees[3];
}
}
vector<int> solution(vector<int> fees, vector<string> records) {
vector<int> answer;
set<string> car_names;
map<string, vector<int>> cars;
//차량별로 입/출차 기록을 저장한다.
for(int i=0; i<records.size(); i++){
stringstream ss(records[i]);
string time, car, state;
ss >> time >> car >> state;
int hour = (time[0]-'0')* 10 + (time[1] - '0');
int minute = (time[3]-'0')* 10 + (time[4] - '0');
cars[car].push_back(hour*60 + minute);
car_names.insert(car);
}
//차량별로 누적 주차 시간(출차-입차 시간의 합)을 구한다.
for(auto idx : car_names){
int car_nums = cars[idx].size();
int park_times = 0;
if(car_nums % 2 == 1){
//입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주한다.
park_times = (1439 - cars[idx][car_nums-1]);
car_nums -= 1;
}
for(int i=0; i< car_nums; i+=2){
park_times += (cars[idx][i+1]-cars[idx][i]);
}
answer.push_back(park_fees(fees, park_times));
}
return answer;
}
☝️이때, 코드에서 중요한 점을 요약해보면
1️⃣ 공백을 단위로 문자열을 끊어주는 함수를 사용하여, 시간과 차량번호, 입출차 상태를 문자열에 저장한다!!
stringstream ss(records[i])
2️⃣ 여기에서 입출차 상태를 사용하지 않는데, 그 이유는 여기에서 무조건 입차 다음에는 출차가 입력된다는 조건이 있기 때문이다.
3️⃣ set을 사용하여 차량번호를 정렬한다.
set<string> car_names;
4️⃣ 시간을 빼고 계산하는 과정이 있으면, 시간을 분으로 변환하여 저장해주는 것이 시간 계산에 편리하다!!
int hour = (time[0]-'0')* 10 + (time[1] - '0');
int minute = (time[3]-'0')* 10 + (time[4] - '0');
cars[car].push_back(hour*60 + minute);