Level. 2
문제
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다.
아래는 하나의 예시를 나타냅니다.
요금표
기본 시간(분) | 기본 요금(원) | 단위 시간(분) | 단위 요금(원) |
180 | 5000 | 10 | 600 |
입/출차 기록
시각(시:분) | 차량 번호 | 내역 |
05:34 | 5961 | 입차 |
06:00 | 0000 | 입차 |
06:34 | 0000 | 출차 |
07:59 | 5961 | 출차 |
07:59 | 0148 | 입차 |
18:59 | 0000 | 입차 |
19:09 | 0148 | 출차 |
22:59 | 5961 | 입차 |
23:00 | 5961 | 출차 |
자동차별 주차 요금
차량 번호 | 누적 주차 시간(분) | 주차 요금(원) |
0000 | 34 + 300 = 334 | 5000 + ⌈(334 - 180) / 10⌉ x 600 = 14600 |
0148 | 670 | 5000 +⌈(670 - 180) / 10⌉x 600 = 34400 |
5961 | 145 + 1 = 146 | 5000 |
- 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
- 누적 주차 시간이 기본 시간이하라면, 기본요금을 청구합니다.
- 누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간마다 단위 요금을 청구합니다.
주차 요금을 나타내는 정수 배열 fees,
자동차의 입/출차 내역을 나타내는 문자열 배열 records
가 매개변수로 주어집니다.
차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
* 제한사항
- fees의 길이 = 4
- 1 ≤ records의 길이 ≤ 1,000
풀이
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <iostream>
using namespace std;
vector<int> solution(vector<int> fees, vector<string> records) {
vector<int> answer;
map<string ,int> m;
map<string ,int> totalTime;
for(int i=0; i<records.size(); i++){
string num = records[i].substr(6, 4); // 차넘버
if(records[i][11] == 'I') {// IN
int time =(records[i][0]-'0') * 60 * 10
+ (records[i][1]-'0') * 60
+ (records[i][3]-'0') * 10
+ (records[i][4]-'0');
m[num] = time;
}
else { // out
int time =(records[i][0]-'0') * 60 * 10
+ (records[i][1]-'0') * 60
+ (records[i][3]-'0') * 10
+ (records[i][4]-'0');
int ttime = time - m[num];
totalTime[num] += ttime;
m[num] = -1;
}
}
for (auto iter : m) {
if(iter.second != -1){ // 출차된 내역이 없을경우, 23:59 에 출차된 것으로 간주
int time = 23*60 + 59;
int ttime = time - iter.second;
totalTime[iter.first] += ttime;
}
}
for (auto iter : totalTime) {
int totalFee = 0;
if(iter.second > fees[0]){
totalFee = ceil((double)(iter.second-fees[0])/fees[2])*fees[3];
}
totalFee += fees[1];
answer.push_back(totalFee);
}
return answer;
}
map은 기본적으로 key를 기준으로 오름차순 정렬이된다.
ceil()
소수점 자리를 올린 정수값을 반환한다.
해결방법
- 누적 주차 시간을 분 단위의 숫자로 저장하여 계산하였다.
- 차량 번호 별 입차시간, 전체 누적 주차 시간을 저장하기 위해 map 자료구조를 사용하였다.
차량번호(문자열)를 key로, 누적시간을 value로 사용하기 위해서이다.
다른 풀이
#include <bits/stdc++.h>
using namespace std;
int conv(string& t) {
int h = (t[0] - 48) * 10 + t[1] - 48;
int m = (t[3] - 48) * 10 + t[4] - 48;
return h * 60 + m;
}
vector<int> solution(vector<int> fees, vector<string> records) {
vector<int> vec[10000];
for (auto& record : records) {
stringstream ss(record);
string a, b, c;
ss >> a >> b >> c;
vec[stoi(b)].push_back(conv(a));
}
vector<int> ans;
for (int i = 0; i < 10000; ++i) if (!vec[i].empty()) {
if (vec[i].size() & 1) vec[i].push_back(23 * 60 + 59); // 출차시간이 없을경우 23:59 추가
int sum = 0;
for (int j = 1; j < vec[i].size(); j += 2) sum += vec[i][j] - vec[i][j - 1];
int val = fees[1];
if (sum > fees[0]) val += (sum - fees[0] + fees[2] - 1) / fees[2] * fees[3];
ans.push_back(val);
}
return ans;
}
1. 크기 10000짜리의 벡터를 만들어 index를 차량번호로 사용하였다.
2. 차량 index에 입차시간, 출차시간을 분단위 숫자로 만들어 insert 해주고, value의 개수가 홀수일 경우 출차시간이 없다는 의미이므로 23:59를 추가해 주었다.
신기한 풀이다!
https://school.programmers.co.kr/learn/courses/30/lessons/92341
'Algorithm > 카카오기출' 카테고리의 다른 글
[프로그래머스] 프렌즈4블록 (1) | 2023.10.17 |
---|---|
[프로그래머스] [3차] 파일명 정렬 / stable_sort (1) | 2023.10.14 |
[프로그래머스] [3차] n진수 게임 (0) | 2023.09.28 |
[프로그래머스] [3차] 압축 (1) | 2023.09.16 |
[프로그래머스] k진수에서 소수 개수 구하기 (0) | 2023.09.16 |