[문제 링크]
https://school.programmers.co.kr/learn/courses/30/lessons/92341
문제 설명
주차장의 요금표와 차량들의 입차, 출차 기록이 주어질 때, 차량별로 주차 요금을 계산해서 차량번호가 작은 자동차부터 순서대로 주차요금을 출력한다.
- 누적 주차 시간 <= 기본 시간 : 기본 요금
- 누적 주차 시간 > 기본시간 : 기본요금 + (초과시간에 대해 단위시간당 요금 청구)
- 초과시간이 단위 시간으로 나누어떨어지지 않으면 올림해서 계산
- 어떤 차량이 입차된 후에 출차된 내역이 없다면 23:59에 출차된 것으로 간주하고 계산
문제 풀이
알고리즘 분류
- 구현
- HashMap
문제는 이해했는데 구현을 하는데 시간이 오래걸렸다.
처음에는 먼저 차량번호와 시각 기준 오름차순 정렬한 후에, 차량번호가 작은 순서부터 차례로 순회하면서 차량별 총 주차 시간을 구하려 했다. 근데 생각해보니 하나의 차량번호에 여러 개의 입출차 내역이 있는데, 굳이 이 많은 내역을 처음부터 정렬할 필요 없이 차량별 총 주차시간을 모두 구한 후에 정렬해도 된다.
하나의 문자열로 되어있는 입출차내역을 시간, 분, 차량번호, 입출차내역으로 나눈다.
String[] record = s.split(" ");
String[] time = record[0].split(":");
int hour = Integer.parseInt(time[0]); //시간
int minute = Integer.parseInt(time[1]); //분
String number = record[1]; //차량번호
String state = record[2]; //입출차 내역
입출차내역이 "IN"이면 map에 삽입, "OUT"이면 map에서 같은 차량번호의 정보를 꺼내서 주차 시간을 계산한다. → calculate() 함수 사용
if(state.equals("IN")) {
map.put(number, new int[]{hour, minute});
} else {
int[] t = map.get(number);
calculate(number, t[0], t[1], hour, minute);
}
한 번 순회가 끝나고 map에 남아있는 차량들은 입차내역은 있지만 출차내역이 없는 차량이다.
이 경우 23:59에 출차한 것으로 간주하고 주차 시간을 계산한다. → calculate() 함수 사용
if(map.size() != 0) {
ArrayList<String> list = new ArrayList<>(map.keySet());
for(String key : list) {
int[] t = map.get(key);
calculate(key, t[0], t[1], 23, 59);
}
}
차량별 총 주차 시간이 담겨 있는 sumMap을 사용해서 차량별 총 주차 요금을 계산한다.
이 때, sumMap의 key들을 오름차순 정렬해서 차량번호가 작은 자동차부터 순서대로 계산할 수 있게 한다.
ArrayList<String> keys = new ArrayList<>(sumMap.keySet());
Collections.sort(keys);
int[] answer = new int[sumMap.size()];
int idx = 0;
for(String key : keys) {
int time = sumMap.get(key);
int extraFee = 0;
if(time > fees[0]) {
double extraTime = Math.ceil((double)(time - fees[0]) / (double)fees[2]);
extraFee = (int)extraTime * fees[3];
}
answer[idx] = fees[1] + extraFee;
idx++;
}
전체코드
import java.util.*;
class Solution {
HashMap<String, Integer> sumMap = new HashMap<>(); //차랑번호별 총 주차 시간을 담는다.
HashMap<String, int[]> map = new HashMap<>(); //차량번호별 입차 시각을 담는다.
public int[] solution(int[] fees, String[] records) {
//시간, 분, 차량번호, 내역별로 나누기
for(String s : records) {
String[] record = s.split(" ");
String[] time = record[0].split(":");
int hour = Integer.parseInt(time[0]); //시간
int minute = Integer.parseInt(time[1]); //분
String number = record[1]; //차량번호
String state = record[2]; //입출차 여부
//"IN"이면 map에 삽입, "OUT"이면 map에서 같은 차량번호의 정보를 꺼내서 시간 계산
if(state.equals("IN")) {
map.put(number, new int[]{hour, minute});
} else {
int[] t = map.get(number);
calculate(number, t[0], t[1], hour, minute);
}
}
//출차 안된 차량들의 주차 시간 계산
if(map.size() != 0) {
ArrayList<String> list = new ArrayList<>(map.keySet());
for(String key : list) {
int[] t = map.get(key);
calculate(key, t[0], t[1], 23, 59);
}
}
//차량번호 기준 오름차순 정렬
ArrayList<String> keys = new ArrayList<>(sumMap.keySet());
Collections.sort(keys);
//차량별 총 주차 요금 계산
int[] answer = new int[sumMap.size()];
int idx = 0;
for(String key : keys) {
int time = sumMap.get(key);
int extraFee = 0;
if(time > fees[0]) {
double extraTime = Math.ceil((double)(time - fees[0]) / (double)fees[2]);
extraFee = (int)extraTime * fees[3];
}
answer[idx] = fees[1] + extraFee;
idx++;
}
return answer;
}
//차량별 총 주차 시간 계산
public void calculate(String num, int inH, int intM, int outH, int outM) {
int tmp_h = outH - inH;
int tmp_m = 0;
if(outM < intM) {
tmp_m = (60 + outM) - intM;
tmp_h -= 1;
} else {
tmp_m = outM - intM;
}
int total = tmp_h * 60 + tmp_m;
sumMap.put(num, sumMap.getOrDefault(num, 0) + total);
map.remove(num); //map에서 같은 차량번호 정보 삭제
}
}'PS > 프로그래머스' 카테고리의 다른 글
| [프로그래머스] 예상 대진표 (JAVA/자바) (0) | 2026.02.10 |
|---|---|
| [프로그래머스] 야근지수 (JAVA/자바) (0) | 2026.02.03 |
| [프로그래머스]완주하지 못한 선수 (JAVA/자바) (0) | 2025.10.22 |
| [프로그래머스] 여행경로 (JAVA/자바) (0) | 2025.09.18 |