본문 바로가기
알고리즘

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;
    }
}

댓글