본문 바로가기
알고리즘

Programmers - 주차 요금 계산(Java)

by 장중앙 2022. 2. 13.

https://programmers.co.kr/learn/courses/30/lessons/92341

 

코딩테스트 연습 - 주차 요금 계산

[180, 5000, 10, 600] ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"] [14600, 34400, 5000]

programmers.co.kr

 

2개의 map과 한 개의 set을 이용해 누적 시간 및 차량 내역을 기록

정산한 후 다시 주차하는 차량도 있기 때문에 차량번호가 중복되지 않게 Set을 이용해 기록

요금 계산 시, 분 단위로 계산하기 때문에 편의상 map의 value는 분 단위로 저장 ex) 05:23 = (5 x 60) + 23 = 323분


records 순회 탐색

startTime에 해당 차량 번호의 유무로 추차된 차량인지 정산하는 차량인지를 확인

    - startTime에 없는 차량번호라면 주차하는 차량

        - 차량 번호 저장 carSet

        - 주차 시작 시간 기록

        - 누적 시간 map에 존재하지 않는 차량이라면 <key, value>초기화

    - startTime에 없는 차량  번호라면 나가는 차량

        - 누적 시간에 (현재 시간 - startTime의 value)분 만큼 합

        - 해당 키의 startTime clear

 

for (String s : records) {
// records 자르기
String[] str = s.split(" ");
// 시:분 자르기
String[] times = str[0].split(":");
int min = (Integer.parseInt(times[0]) * 60) + Integer.parseInt(times[1]);
int num = Integer.parseInt(str[1]);
if (!startTime.containsKey(num)) {
carSet.add(num);
startTime.put(num, min);
if (!totalTime.containsKey(num)) {
totalTime.put(num, 0);
}
} else {
totalTime.put(num, totalTime.get(num) + min - startTime.get(num));
startTime.remove(num);
}
}

 

아직 출차된 내역이 없는차량 처리

startTime 맵에 아직 남아있는 요소는 출차된 내역이 없음 -> 출차된 내역이 없으면 23:59에 출차된 것으로 간주

현재까지의 누적 추자 시간에 INF - 주차 시작 시간을 합

* INF = (23 x 60) + 59

for (Integer key : startTime.keySet()) {
totalTime.put(key, totalTime.get(key) + INF - startTime.get(key));
}

 

요금 계산

carSet에 저장된 차량 내역을 List로 변환, 정렬

숫자가 작은 차량부터 요금을 계산

    - 누적 시간이 기본 시간(fees[0])보다 작다면 기본요금(fees[1])만 계산

    - 누적 시간이 기본 시간보다 크다면 기본요금(fees[1])에 초과시간(누적시간 - 기본시간(fees[0]))만큼 계산

        - 초과된 시간이 단위 시간으로 나눠지지 않으면 올림 처리

List<Integer> list = new ArrayList<>(carSet);
Collections.sort(list);
answer = new int[carSet.size()];
int idx = 0;
for (int num : list) {
int time = totalTime.get(num);
if (time <= fees[0]) {
answer[idx] = fees[1];
} else {
answer[idx] = (int) (fees[1] + Math.ceil((double) (time - fees[0]) / fees[2]) * fees[3]);
}
idx++;
}

전체 코드

import java.util.*;
class Solution {
public int[] solution(int[] fees, String[] records) {
int[] answer = {};
int INF = 23 * 60 + 59;
Map<Integer, Integer> startTime = new HashMap<>();
Map<Integer, Integer> totalTime = new HashMap<>();
Set<Integer> carSet = new HashSet<>();
for (String s : records) {
// records 자르기
String[] str = s.split(" ");
// 시:분 자르기
String[] times = str[0].split(":");
int min = (Integer.parseInt(times[0]) * 60) + Integer.parseInt(times[1]);
int num = Integer.parseInt(str[1]);
if (!startTime.containsKey(num)) {
carSet.add(num);
startTime.put(num, min);
if (!totalTime.containsKey(num)) {
totalTime.put(num, 0);
}
} else {
totalTime.put(num, totalTime.get(num) + min - startTime.get(num));
startTime.remove(num);
}
}
for (Integer key : startTime.keySet()) {
totalTime.put(key, totalTime.get(key) + INF - startTime.get(key));
}
List<Integer> list = new ArrayList<>(carSet);
Collections.sort(list);
answer = new int[carSet.size()];
int idx = 0;
for (int num : list) {
int time = totalTime.get(num);
if (time <= fees[0]) {
answer[idx] = fees[1];
} else {
answer[idx] = (int) (fees[1] + Math.ceil((double) (time - fees[0]) / fees[2]) * fees[3]);
}
idx++;
}
return answer;
}
}

댓글