https://school.programmers.co.kr/learn/courses/30/lessons/92341
코딩테스트 연습 > 2022 KAKAO BLIND RECRUITMENT > 주차 요금 계산
문제 접근
구현 문제!!
문제의 핵심
1. records에 기록된 차량의 입/출차 내역은 시간의 오름차순 순서대로 기록 (00:00 ~ 23:59)
2. records에 기록된 차량의 입/출차 내역은 오류가 없다.
3. records에 입차 내역은 있는데 출차 내역이 없으면 출차는 23:59에 한다
4. 하루에 입/출차를 여러번 하는 케이스가 있다 요금 정산은 매번 입/출차 마다 하는 게 아니라 하루에 전체 사용 시간을 기준으로 정산을 한다. 즉 누적 주차 시간
5. 누적 주차 시간이 기본 시간 이하라면 기본 요금 청구
6. 누적 주차 시간이 기본 시간을 초과하면 초과한 시간에 대해서 단위 시간 마다 단위 요금 청부(올림)
문제 로직 설명
1. func(records) 메서드 & calculate 메서드
static HashMap<String, ArrayList<Integer>> map = new HashMap<>();
public static void func(String [] records){
for(String target : records){
String [] split = target.split(" ");
int time = calculate(split[0]); // 시간 계산
String carNum = split[1]; // 차량 번호
if(map.containsKey(carNum)){
map.get(carNum).add(time);
}
else{
ArrayList<Integer> temp = new ArrayList<>();
temp.add(time);
map.put(carNum, temp);
}
}
}
public static int calculate(String time){
String [] split = time.split(":");
int cur = 0;
cur += Integer.parseInt(split[0]) * 60; // 시
cur += Integer.parseInt(split[1]); // 분
return cur;
}
func 메서드는 records를 바탕으로 map 자료구조에 데이터를 넣는다.
map key: 차량번호 value: ArrayList<Integer> 입/출차 시간
입/출차 시간을 calculate() 메서드를 통해서 간편하게 구했다.
records는 시간 순서대로 들어오고 입/출차 내역엔 문제가 없으니까
항상 입차/출차 순서대로 들어온다!
2. List<String> list = func2();
List<String> list = func2();
public static List<String> func2(){
ArrayList<String> list = new ArrayList<>(map.keySet());
Collections.sort(list); // 차량 번호가 작은 자동차 순서
return list;
}
map의 key를 바탕으로 차량 번호가 작은 순서대로 정렬을 해서 List를 반환한다.
3. return func3(list, fees); 문제의 핵심 로직
return func3(list, fees);
public static int [] func3(List<String> list, int [] fees){
// fees 0: 기본시간 1: 기본요금 2: 단위시간 3: 단위요금
int insert = (23 * 60) + 59;
int [] answer = new int [list.size()];
int cnt = 0;
for(String key : list){
List<Integer> temp = map.get(key);
if(temp.size() % 2 == 1) temp.add(insert);
int fee = 0;
int time = 0;
for(int i = 0; i < temp.size(); i+=2){
time += temp.get(i+1) - temp.get(i);
}
time -= fees[0]; // 기본시간
fee += fees[1]; // 기본요금
if(time > 0){
fee += (time / fees[2]) * fees[3];
if(time % fees[2] != 0){
fee += fees[3];
}
}
answer[cnt++] = fee;
}
return answer;
}
int insert
입/출차 내역이 홀수 즉 pair를 이루지 못한다면 출차 내역이 하나가 없는 케이스이다.
이런 경우 마지막 시간을 넣어준다.(23 * 60 + 59) == (23:59)
차량 번호가 작은 순서대로 (for String key : list) 를 돌면서 요금 정산을 한다.
해당 차량 번호의 입/출차 내역이 홀수인 경우 미리 정의한 insert를 리스트에 넣는다.
int insert = (23 * 60) + 59;
각 구간마다 시간을 구한다 구간이란 출차 - 입차 시간
이런 구간을 모두 더해서 해당 차량 번호의 누적 주차 시간을 구한다.
int time = 0;
for(int i = 0; i < temp.size(); i+=2){
time += temp.get(i+1) - temp.get(i);
}
요금 정산 로직
먼저 기본요금을 계산한다.
기본 금을 계산하고 그래도 시간이 남는다면 단위 시간으로 초과 요금을 계산한다
이때 나머지 즉 나누어떨어지지 않는 시간은 올림 처리한다.
time -= fees[0]; // 기본시간
fee += fees[1]; // 기본요금
if(time > 0){
fee += (time / fees[2]) * fees[3];
if(time % fees[2] != 0){
fee += fees[3];
}
}
정답 코드
import java.util.*;
class Solution {
static HashMap<String, ArrayList<Integer>> map = new HashMap<>();
public int[] solution(int[] fees, String[] records) {
func(records);
List<String> list = func2();
return func3(list, fees);
}
public static void func(String [] records){
for(String target : records){
String [] split = target.split(" ");
int time = calculate(split[0]); // 시간 계산
String carNum = split[1]; // 차량 번호
if(map.containsKey(carNum)){
map.get(carNum).add(time);
}
else{
ArrayList<Integer> temp = new ArrayList<>();
temp.add(time);
map.put(carNum, temp);
}
}
}
public static int calculate(String time){
String [] split = time.split(":");
int cur = 0;
cur += Integer.parseInt(split[0]) * 60; // 시
cur += Integer.parseInt(split[1]); // 분
return cur;
}
public static List<String> func2(){
ArrayList<String> list = new ArrayList<>(map.keySet());
Collections.sort(list); // 차량 번호가 작은 자동차 순서
return list;
}
public static int [] func3(List<String> list, int [] fees){
// fees 0: 기본시간 1: 기본요금 2: 단위시간 3: 단위요금
int insert = (23 * 60) + 59;
int [] answer = new int [list.size()];
int cnt = 0;
for(String key : list){
List<Integer> temp = map.get(key);
if(temp.size() % 2 == 1) temp.add(insert);
int fee = 0;
int time = 0;
for(int i = 0; i < temp.size(); i+=2){
time += temp.get(i+1) - temp.get(i);
}
time -= fees[0]; // 기본시간
fee += fees[1]; // 기본요금
if(time > 0){
fee += (time / fees[2]) * fees[3];
if(time % fees[2] != 0){
fee += fees[3];
}
}
answer[cnt++] = fee;
}
return answer;
}
}
'Algorithm > Programmers Java' 카테고리의 다른 글
[JAVA] 프로그래머스 level2 메뉴 리뉴얼 (0) | 2024.08.05 |
---|---|
[JAVA] 프로그래머스 level2 할인 행사 (0) | 2024.07.29 |
[JAVA] 프로그래머스 level2 순위 검색 (0) | 2024.07.27 |
[JAVA] 프로그래머스 level2 양궁대회 (5) | 2024.07.24 |
[JAVA] 프로그래머스 level2 두 큐 합 같게 만들기 (0) | 2024.07.23 |