일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 브루트포스
- kotlin
- 누적합
- Lv3
- dp
- const
- 호이스팅
- 2022 KAKAO BLIND RECRUITMENT
- 프로그래머스
- BFS
- 코틀린
- 백준
- 컴퓨터비전
- js
- VAR
- 동적계획법
- 2021 KAKAO BLIND RECRUITMENT
- 컴퓨터 비전
- 자바스크립트
- lv2
- 2023 KAKAO BLIND RECRUITMENT
- 삼성SW역량테스트
- 2018 KAKAO BLIND RECRUITMENT
- 구현
- JavaScript
- 자바
- level3
- level2
- 유니온파인드
- java
- Today
- Total
코드를 느껴바라
Lv2. 주차 요금 계산 [JAVA] 본문
문제링크
성공 여부(걸린 시간): 성공(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 |