Algorithm/programmers

[2022 카카오 블라인드]주차 요금 계산

마닐라 2022. 5. 3. 18:10

📍 문제 설명

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

 

💡 접근

차 번호순으로 정렬 시킨다음 차번호, 주차시간으로 맵에 담아서 주차요금을 계산했다.

마지막 테스트케스트가 계속 틀렸다고 나와서 해당 부분은 다른 자료를 참고했다.

 

 

👩‍💻 코드

내풀이

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

class Car implements Comparable<Car> {
    private String time;
    private String car;
    private String history;

    public Car(String time, String car, String history) {
        this.time = time;
        this.car = car;
        this.history = history;
    }

    public String getTime() {
        return time;
    }

    public String getCar() {
        return car;
    }

    public String getHistory() {
        return history;
    }

    @Override
    public int compareTo(Car o) {
        return Integer.parseInt(this.car) - Integer.parseInt(o.car);
    }

    @Override
    public String toString() {
        return "time='" + time + '\'' +
                ", car=" + car +
                ", history='" + history + '\'';
    }

}

public class Solution {
    public int[] solution(int[] fees, String[] records) throws ParseException {
        SimpleDateFormat f = new SimpleDateFormat("mm:ss", Locale.KOREA);
        ArrayList<Car> list = new ArrayList<>();
        for(int i = 0; i < records.length; i++) {
            String[] split = records[i].split(" ");
            String time = split[0];
            String car = split[1];
            String history = split[2];

            //차량 하나만 입차했을 경우
            if(records.length == 1) {
                Date d1 = f.parse(split[0]);
                Date d2 = f.parse("23:59");
                long diff = (d2.getTime() - d1.getTime()) / 1000;
                float unitFee = (float) (diff - fees[0]) / fees[2];
                long fee = (long) (fees[1] + Math.ceil(unitFee) * fees[3]);
                return new int[] {(int) fee} ;
            }
            list.add(new Car(time, car, history));
        }

        //차 번호순으로 정렬(시간순으로는 이미 정렬되어 있음)
        Collections.sort(list);
        //차번호, 주차시간
        LinkedHashMap<String, Long> map = new LinkedHashMap<>();

        for(int i = 0; i < list.size() - 1; i++) {
            if(list.get(i).getHistory().equals("OUT")) continue;
            Date d1 = f.parse(list.get(i).getTime());
            Date d2 = f.parse(list.get(i+1).getTime());
            long diff = 0L;
            //차 번호가 같고 현재 'IN' 상태면 주차시간 계산
            if(list.get(i).getCar().equals(list.get(i+1).getCar()) && list.get(i).getHistory().equals("IN")) {
                diff = (d2.getTime() - d1.getTime()) / 1000;
            }
            //차 번호가 같지 않은데 현재 'IN' 상태면 23:59에 출차로 간주
            else if(list.get(i).getHistory().equals("IN")) {
                d2 = f.parse("23:59");
                diff = (d2.getTime() - d1.getTime()) / 1000;
            }

            map.put(list.get(i).getCar(), map.getOrDefault(list.get(i).getCar(), 0L) + diff);
        }

        //마지막에 입차일 경우도 고려해야한다..
        if(list.get(list.size() - 1).getHistory().equals("IN")) {
            Date d1 = f.parse(list.get(list.size() - 1).getTime());
            Date d2 = f.parse("23:59");
            long diff = (d2.getTime() - d1.getTime()) / 1000;
            map.put(list.get(list.size() - 1).getCar(), map.getOrDefault(list.get(list.size() - 1).getCar(), 0L) + diff);
        }

        ArrayList<Long> ans = new ArrayList<>();
        //주차 요금 계산
        for(String s : map.keySet()){
            if(map.get(s) <= fees[0]) {
                ans.add((long) fees[1]);
                continue;
            }
            float unitFee = (float) (map.get(s) - fees[0]) / fees[2];
            long fee = (long) (fees[1] + Math.ceil(unitFee) * fees[3]);
            ans.add(fee);
        }

        int[] answer = new int[map.size()];
        for(int i = 0; i < ans.size(); i++) {
            answer[i] = Math.toIntExact(ans.get(i));
        }

        return answer;
    }

    public static void main(String[] args) throws IOException, ParseException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        Solution s = new Solution();
        //int[] fees = {180, 5000, 10, 600};
        //String[] records = {"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"};
        int[] fees = {120, 0, 60, 591};
        String[] records = {"16:00 3961 IN","16:00 0202 IN","18:00 3961 OUT","18:00 0202 OUT","23:58 3961 IN"};
        s.solution(fees,records);
        int[] fees2 = {1, 461, 1, 10};
        String[] records2 = {"00:00 1234 IN"};
        System.out.println(Arrays.toString(s.solution(fees2, records2)));

    }
}

 

다른 풀이

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;



public class Solution {
    public int[] solution(int[] fees, String[] records) {
        //입차시간을 기록하기 위한 해쉬맵(차번호, 시간)
        HashMap<String, Integer> intime = new HashMap<>();
        //출차시간을 누적 기록하기 위한 트리맵(차번호, 시간)
        TreeMap<String, Integer> result = new TreeMap<>();

        for(String r : records) {
            String[] str = r.split(" ");
            if (str[2].equals("IN")) { intime.put(str[1], convert(str[0]));
            if (!result.containsKey(str[1])) result.put(str[1], 0);
            } else {
                result.put(str[1], result.get(str[1]) + convert(str[0]) - intime.get(str[1]));
                intime.remove(str[1]);
            }
        }

        //intime에 남아있는(출차하지 않은) 차량들 처리
        intime.forEach((key, val) -> {
            result.put(key, result.get(key) + 23 * 60 + 59 - val);
        });

        int[] answer = new int[result.size()];
        int idx = 0;
        //val은 총 주차시간
        for(int val : result.values()) {
            answer[idx] = fees[1];
            if (val > fees[0]) {
                answer[idx] += Math.ceil((val - fees[0]) / (double) fees[2]) * fees[3];
            }
            idx++;
        }
        return answer;
    }

    private int convert(String s) {
        String[] split = s.split(":");
        return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
    }

    public static void main(String[] args) throws IOException, ParseException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        Solution s = new Solution();
        int[] fees = {180, 5000, 10, 600};
        String[] records = {"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"};
        //int[] fees = {120, 0, 60, 591};
        //String[] records = {"16:00 3961 IN","16:00 0202 IN","18:00 3961 OUT","18:00 0202 OUT","23:58 3961 IN"};
        s.solution(fees,records);
        int[] fees2 = {1, 461, 1, 10};
        String[] records2 = {"00:00 1234 IN"};
        System.out.println(Arrays.toString(s.solution(fees2, records2)));

    }
}