코드를 느껴바라

Lv2. 주차 요금 계산 [JAVA] 본문

PS/프로그래머스(Programmers)

Lv2. 주차 요금 계산 [JAVA]

feelTheCode 2025. 3. 19. 16:54
반응형

문제링크

성공 여부(걸린 시간): 성공(32분 47초)

아이디어

일단 문제에서 중요한 키포인트는 한 차량이 들어가고 나가는것이 여러번이 될 수 있다는 것이고
그때마다 정산하는 것이 아닌 일괄적으로 23:59에 정산한다고 생각을 하고 문제를 풀어야한다.
순서대로 설명해보겠다.

 

출입차처리
그래서 나는 한 차량에 대한 누적시간을 저장해줄 HashMap하나 그리고 최근 들어온 시간을 기록해줄 HashMap하나
총 2개의 HashMap을 생성했고 이 2개에 저장된 정보를 바탕으로 마지막에 일괄계산 해주었다.

 

우선 전체적으로 보면 records의 차량 기록을 하나씩 돌면서 출차, 입차 처리를 수행해 주었다.

 

⭕입차는 lastCome 맵에 최근 들어온 입차처리만 해주면 끝이고

 

❌출차는 해당 차에 대한 sumTime기록이 있다면 그것에 누적하여 lastCome과 출차 시간의 차를 더해줘 최신화 해준다.

 

그렇게 되었을때 lastCome에는 있으나 출차기록 없이 반복문이 끝난 경우들은

23:59 기준으로 시간을 더해줘야 하므로 처리한 lastCome시간은 삭제해준다.

 

그리고 모든 출입차 기록에 대한 처리가 끝났다면 아까 lastCome을 삭제해줬던 원래의 목적
남아있는 차량에 대한 23:59 출차처리를 해주면 출입차 처리 끝이다.

 

요금계산
요금계산은 만약 사용요금이 기본요금 시간보다 크다면 기본요금에다 기본요금에 해당하는 시간을 제외한
추가 시간에 요금이 나오는 시간단위로 나눠서 추가요금을 곱해주었다.
만약 나머지가 존재한다면 추가요금을 한번 더 더해주었다.
이부분은 말로하면 어렵지만 코드로 보면 쉬울 것이다.

        for(int car: carSet){
            int cost = fees[1];
            if(sumTime.get(car)>fees[0]){//기본요금보다 많이 나왔을때
                cost+=(sumTime.get(car)-fees[0])/fees[2]*fees[3];
                if((sumTime.get(car)-fees[0])%fees[2]!=0){//나머지가 있으면 요금 추가
                    cost+=fees[3];
                }
            }
            pq.add(new Node(car, cost));
        }

 

그다음엔 마지막에 출력을 차량번호 작은 순으로 해야하기에 Node로 차량번호와 함께 요금을 저장하여
우선순위큐에 넣어준다. 그럼 이제 하나씩 빼면서 배열에 넣어주면 끝이다.

정답 코드

import java.util.*; 
class Solution {
    static class Node{
        int carNum, fee;
        public Node(int carNum, int fee){
            this.carNum = carNum;
            this.fee = fee;
        }
    }
    public int[] solution(int[] fees, String[] records) {
        PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(o1->o1.carNum));
        HashMap<Integer,Integer> sumTime = new HashMap<>();
        HashMap<Integer,Integer> lastCome = new HashMap<>();
        for(String x: records){
            StringTokenizer st = new StringTokenizer(x);
            String temp = st.nextToken();
            int num = Integer.parseInt(st.nextToken());
            String state = st.nextToken();
            int time = ((temp.charAt(0)-'0')*10+(temp.charAt(1)-'0'))*60+((temp.charAt(3)-'0')*10+(temp.charAt(4)-'0'));
            if(state.equals("IN")){//입차
                lastCome.put(num, time);
            }
            else{
                //누적시간 최신화
                int pre =0;
                if(sumTime.containsKey(num)){
                    pre = sumTime.get(num);
                }
                sumTime.put(num, pre+time-lastCome.get(num));
                lastCome.remove(num);//다끝나고 출차기록 없는 차량들 처리해줘야함
            }
        }
        Set<Integer> remain = lastCome.keySet();
        for(int car: remain){
            int pre =0;
            if(sumTime.containsKey(car)){
                pre = sumTime.get(car);
            }
            sumTime.put(car, pre+23*60+59-lastCome.get(car));
        }
        //누적시간 기반으로 계산
        Set<Integer> carSet = sumTime.keySet();
        for(int car: carSet){
            int cost = fees[1];
            if(sumTime.get(car)>fees[0]){//기본요금보다 많이 나왔을때
                cost+=(sumTime.get(car)-fees[0])/fees[2]*fees[3];
                if((sumTime.get(car)-fees[0])%fees[2]!=0){//나머지가 있으면 요금 추가
                    cost+=fees[3];
                }
            }
            pq.add(new Node(car, cost));
        }
        int[] answer = new int[pq.size()];
        int len =pq.size();
        for(int i =0; i<len; i++){
            answer[i] = pq.poll().fee;
        }
        return answer;
    }
}
//누적 주차 시간을 계산해서 요금은 일괄로 정산함
//map으로 차량번호별로 누적시간 계산해주는것 하나, 입차시간 적어둔거 하나 2개로 관리
//그리고 마지막에 계산해주며 차량번호랑 같이 PriorityQueue에 Node로 넣어주고
//차량번호를 기준으로 하나씩 뽑으면서 넣어주면 끝
반응형

'PS > 프로그래머스(Programmers)' 카테고리의 다른 글

Lv.2 순위 검색 [JAVA]  (0) 2025.03.21
Lv.3 주사위 고르기 [JAVA]  (0) 2025.03.20
Lv.2 단체사진 찍기 [JAVA]  (0) 2025.03.15
Lv.2 캐시 [JAVA]  (0) 2025.03.12
Lv.2 프렌즈4블록 [JAVA]  (3) 2025.03.11