알고리즘/프로그래머스 Level2

[프로그래머스,자바] Level2: 주차 요금 계산

류창 2022. 1. 19. 16:06
반응형

 

문제분석

Level2 답지않게 여러 기술을 많이알아야 풀수있는문제다. (역시 카카오문제)

 

 

문제목표: 차량기록을 모두처리한뒤에,  이용한 차량마다 주차요금 구하기 (차량번호 적은순)

 

 

제일먼저, 요금표에있는 기본시간 (std_time) , 기본요금 (std_pay) , 단위 시간(per_time), 시간당 요금(per_pay)

로 알기쉽게 분리해놨다.

 

그리고 우리가 문제를 풀기위해서 2개의 Map을 준비했다. 

첫번째, 이용시간을 구하기위한 Key= 차량너버, value=입장시간인 맵 하나와

두번째, 각 차량넘버의 이용비를 저장하는 Key=넘버 ,value=이용비 맵 하나를 준비했다.

그리고, 차랑넘버순으로 정렬을 해줘야하니 TreeMap으로 설정해뒀다.

 

주차기록을 처리하는 로직이다.

 

기록의 문자열을 정리하여  time(시간) , car_num(차량번호), state(상태) 를 저장한다.

 

상태가 Out이라면  Map에 저장된 차량넘버의 입장시간을 가져와

나간시간 - 입장시간을 계산하여  이용시간을저장한다. 

-> 이때, Out처리한 Map은 삭제를해놔야한다.

 

상태가 In이면, Map에 저장한다.

아직 안나간 차량을 처리해야한다.  Out기록이없이 맵에 남아있는사람들을 나가게 처리해야한다.

 

23:59분은 1439분이므로 1439-start를 한다.

 

여기서 중요한게, Map은 Integer인 Wrapper클래스이므로,  산술을하려면 int형으로 언박싱을해줘야한다.

 

Integer의특징중 하나가 값이0인걸 가져오면 null로 처리해버린다.

-> 따라서 null을 int로 변환하면 nullpointerEx 오류가터진다. 그러므로, null을 0으로 치환한뒤에 바꿔야한다.

 

 

그후, result에 기록을 저장한다.

 

 

저장한 result의 값을 가져와서, 비용으로 계산을해야한다.

 

기본시간 이하라면, 기본요금으로 바꾸고

 

기본시간이 넘는다면 공식을사용한다.

 

기본요금 + 올림[시간-기본시간/ 단위 ]*단위당 시간을 한다.

 

올림 메소드는 Math.ceil을 사용한다. ceil메소드를 사용할때 주의점은

먼저 안에있는 식을 double로 변환하고, 올린값을 int형으로 다시 변환을 해줘야한다.

 

-> 안에있는식을 double로 변환을안하면 소수점이 나타나지않음

-> 올린값을 int형으로 변환하지않으면  lossy오류가뜸

 

문제풀이

 풀이과정의 전문

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.util.*;
 
class Solution {
    public int[] solution(int[] fees, String[] records) {
 
        int std_time =fees[0];
        int std_pay=fees[1];
        int per_time=fees[2];
        int per_pay=fees[3];
 
        // Key= 차량넘버 value= 입장시간
        Map<Integer,Integer> map = new HashMap<>();
        // Key= 차량넘버 value= 이용비
        Map<Integer,Integer> result = new TreeMap<>();
        // 주차기록 처리하기
        for(String data: records){
            String[] temp =data.split(" ");
            int time = cal_time(temp[0]);
            int car_num= Integer.parseInt(temp[1]);
            String state= temp[2];
            if(state.equals("OUT")){
               int start=map.get(car_num);
               int use_time= time-start;            
                if(result.containsKey(car_num)){
                  int a=result.get(car_num);
                  use_time+=a;
                }
                result.put(car_num,use_time);
                map.remove(car_num);
                continue;
            }
            map.put(car_num,time);
        }
 
        // 아직 안나간 차량 처리
            for(int num :map.keySet()){
                Integer d=map.get(num);
                d = d==null?0:d;
 
                int start = d.intValue();
                int use_time=1439-start;
 
                Integer e=result.get(num);
                e = e==null?0:e;
 
                int total= e.intValue();
 
                result.put(num,total+use_time);
            }
 
        // 출력하기
        int[] answer = new int[result.size()];
        int i=0;
        for(int data: result.keySet()){
            int time=result.get(data);
 
            if(time<=std_time){
                time=std_pay;
            }
            else{
                time=std_pay+(int)Math.ceil((double)(time-std_time)/per_time)*per_pay;
            }      
            answer[i]=time;
            i++;
        }
 
        return answer;
    }
 
     public int cal_time(String time){
        String[] temp= time.split(":");
        int hour= Integer.parseInt(temp[0])*60;
        int min= Integer.parseInt(temp[1]);       
        return hour+min;
    }
}
cs
반응형