[코딩테스트 - Java] 프로그래머스 - 2022 KAKAO BLIND RECRUITMENT - 주차 요금 계산

김수빈·2022년 10월 24일
0

코딩테스트

목록 보기
10/16

주차 요금 계산 - 해시

INPUT

차량의 입/출차 시간, 차량 번호, 내역

조건

출차 내역이 없으면 23:59에 출차된 것

입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산

누적 주차 시간이 기본 시간이하라면 기본 요금을 청구
누적 주차 시간이 기본 시간을 초과하면 기본 요금에 더해서 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구
초과한 시간이 단위 시간으로 나누어 떨어지지 않으면 올림합니다.

OUTPUT

차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 담은 정수 배열

LOGIC

해시맵을 이용해서 풀었다.
<차량번호,총 주차시간> 을 가지는 carAndTime,
<차량번호, 입차시간> 을 가지는 carAndIO 를 만들었다.

이후 records 에서 필요한 정보를 파싱한다.
해당 차량이 carAndTime 에 존재하는 않는 경우에는 입차 이므로, 두 해시맵 모두 추가해준다.
반대의 경우에는 출차하는 경우 이므로, carAndIO 에서 삭제하고 해당 차량의 주차 시간을 carAndTime 에서 업데이트 해준다.

이후 carAndIO 에 원소가 들어있는 경우는 23:59 가 지나도 출차 기록이 없는 상태이다. 해당 경우를 처리해준다.

마지막으로 정답 배열에 사용할 cars 를 자동차 번호 오름차순으로 정렬하고 각 차량 별 요금을 계산한다.

import java.util.HashMap;
import java.util.Collections;
import java.util.ArrayList;

class Solution {
    public int[] solution(int[] fees, String[] records) {
        // fees[0]  기본시간(분)
        // fees[1]  기본요금
        // fees[2]  단위시간(분)
        // fees[3]  단위요금

        // 차량번호와 시간 담기
        HashMap<String,Integer> carAndTime = new HashMap<>();

        // 입차 차량의 번호와 입차시간
        HashMap<String,Integer> carAndIO = new HashMap<>();
        
        // 자동차 리스트
        ArrayList<String> cars = new ArrayList<>();
        
        for(String data : records){
            // records에 들어온 값을 파싱
            //  시간 / 차 번호 / 입,출
            String[] inf = data.split(" ");
            int timeInfo = getMin(inf[0]);
            String carNum=inf[1];
            String inOrOut=inf[2];
            
            if(!carAndTime.containsKey(carNum)){
                carAndTime.put(carNum,0);
                cars.add(carNum);
            }
            
            // 입차 일 경우 입차 해시맵에 추가
            if(inOrOut.equals("IN")){
                carAndIO.put(carNum,timeInfo);
            }
            
            // 출차 일 경우 해당 차의 누적시간에 추가 후 입차 해시맵에서 삭제
            else{
                // 입차시간
                int in = carAndIO.get(carNum);

                // 출차시간 - 입차시간 (분)
                int totalTime = timeInfo-in;

                carAndTime.put(carNum,carAndTime.get(carNum)+totalTime);

                carAndIO.remove(carNum);
            }

        }
        if(!carAndIO.isEmpty()){
            for(String data : carAndIO.keySet()){
                carAndTime.put(data,carAndTime.get(data)+1439-carAndIO.get(data));
            }
        }
        
        Collections.sort(cars);
        int[] answer = new int[cars.size()];
        for(int i=0;i<cars.size();i++){
            answer[i]=calcFee(fees,carAndTime.get(cars.get(i)));
        }


        return answer;
    }

    public static int getMin(String time){
        return Integer.parseInt(time.substring(0,2))*60+Integer.parseInt(time.substring(3,5));
    }


    public static int calcFee(int[] fees, int min){
        // 기본시간 이하 일 시
        if(min<=fees[0]){
            // 기본요금 
            return fees[1];
        }
        else{
            //기본 시간을 제외한 초과 시간 
            int a = (int)Math.ceil((min-fees[0])/(double)fees[2]);
            return fees[1]+a*fees[3];
        }
    }
    
}

0개의 댓글