저번 카카오 공채 시험에서 나왔던 문제이다.
그때는 시간이 부족해서 대강 로직만 생각하고 풀지 못했었다...
이번에는 코드 작성에 40분 정도 걸렸고
주차 요금을 계산하는 방식을 잘못 이해해서 수정에 20분,
런타임 에러가 계속 나서 디버깅하는데 20분이 걸렸다.
충분히 풀 수 있는 문제이지만 풀이 시간이 발목을 좀 잡는 것 같다.
구현을 얼마나 빠르게 하는지가 관건인데... 역시 연습밖에 답이 없는 것 같다.
필요한 알고리즘이 없어서 문제에서 요구한 대로 구현하면 된다.
내가 잘못 이해했던 포인트는
주차 요금 계산은 모든 입력이 끝나고 한번에 계산해야 한다는 것이다.
처음에는 이 조건을 잘못 이해해서 출차가 일어날때마다 요금 계산을 했는데 이렇게 하면
테스트 케이스 1번에 0000 차량은 34분 - 5000원 + 300분 - 12200원으로 총금액이 17200원이 나온다.
그런데 문제에서 요구한 계산 방식이라면 334분을 한번에 계산하는 것으로 14600원이 나와야 한다.
그래서 총 주차시간을 parseMap에 넣고 한번에 계산하는 방식으로 수정했다.
시간 변환도 여러 방식이 떠올라서 2가지 방법으로 풀어보았다.
처음에는 SimpleDateFormat을 사용해서 풀었는데
다 풀고 보니 쓰지 않고도 충분히 해결할 수 있을것 같아 split을 사용해서 풀었다.
수행 시간을 보니 SimpleDateFormat을 쓰지 않는게 훨씬 더 빠르다.
최종 코드 (SimpleDateFormat 사용)
import java.text.SimpleDateFormat;
import java.util.*;
class Solution {
static Map<String, Integer> parseMap;
public int[] solution(int[] fees, String[] records) throws Exception{
// 출입시간을 기록하기 위한 map
Map<String, String> map = new HashMap<>();
// 차량 번호별 총 주차시간을 계산하기 위한 map
parseMap = new TreeMap<>();
for (int i = 0; i < records.length; i++) {
String[] tempRecords = records[i].split(" ");
// 입차라면
if (tempRecords[2].equals("IN")) {
map.put(tempRecords[1], tempRecords[0]);
// 출차라면 입차시간, 출차시간, 차량번호를 cul에 넘김
} else {
parse(map.get(tempRecords[1]), tempRecords[0], tempRecords[1]);
map.remove(tempRecords[1]);
}
}
// map에 남아있는 차량이 있다면
if (!map.isEmpty()) {
for (String s : map.keySet()) {
parse(map.get(s), "23:59", s);
}
}
// 계산 메서드 호출
cul(fees);
// map에 value를 담아오기 위한 list
List<Integer> list = new ArrayList<>();
for (String key : parseMap.keySet()) {
list.add(parseMap.get(key));
}
// list를 array로 변환
int[] answer = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
// 주차 시간을 변환하기 위한 메서드
static void parse(String in, String out, String carNum) throws Exception {
// 시간 형식 지정을 위한 simpleDateFormat
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
// 출차 시간
Date outTime = simpleDateFormat.parse(out);
// 입차 시간
Date inTime = simpleDateFormat.parse(in);
// 시간 차이를 구하고 분으로 변환
int dif = (int) ((outTime.getTime() - inTime.getTime()) / 60000);
// parseMap에 업데이트
parseMap.put(carNum, parseMap.getOrDefault(carNum, 0) + dif);
}
// 요금 계산을 위한 메서드
static void cul(int[] fees) {
for (String key : parseMap.keySet()) {
if (parseMap.get(key) < fees[0]) {
parseMap.put(key, fees[1]);
} else {
double addTime = parseMap.get(key) - fees[0];
addTime = Math.ceil(addTime / fees[2]);
int result = (int) (addTime * fees[3] + fees[1]);
parseMap.put(key, result);
}
}
}
}
최종 코드 (split 사용)
import java.util.*;
class Solution {
static Map<String, Integer> parseMap;
public int[] solution(int[] fees, String[] records) {
// 출입시간을 기록하기 위한 map
Map<String, String> map = new HashMap<>();
parseMap = new TreeMap<>();
for (int i = 0; i < records.length; i++) {
String[] tempRecords = records[i].split(" ");
// 입차라면
if (tempRecords[2].equals("IN")) {
map.put(tempRecords[1], tempRecords[0]);
// 출차라면 입차시간, 출차시간, 차량번호를 parse에 넘김
} else {
parse(map.get(tempRecords[1]), tempRecords[0], tempRecords[1]);
map.remove(tempRecords[1]);
}
}
// map에 남아있는 차량이 있다면
if (!map.isEmpty()) {
for (String s : map.keySet()) {
parse(map.get(s), "23:59", s);
}
}
// 계산 메서드 호출
cul(fees);
// map에 value를 담아오기 위한 list
List<Integer> list = new ArrayList<>();
for (String key : parseMap.keySet()) {
list.add(parseMap.get(key));
}
// list를 array로 변환
int[] answer = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
// 총 주차 시간을 계산하기 위한 메서드
static void parse(String in, String out, String carNum) {
// 출차 시간을 분 단위로 변환
String[] outTemp = out.split(":");
int outMin = Integer.parseInt(outTemp[0]) * 60 + Integer.parseInt(outTemp[1]);
// 입차 시간을 분 단위로 변환
String[] inTemp = in.split(":");
int inMin = Integer.parseInt(inTemp[0]) * 60 + Integer.parseInt(inTemp[1]);
// 총 주차시간
int dif = outMin - inMin;
// 주차 시간 업데이트
parseMap.put(carNum, parseMap.getOrDefault(carNum, 0) + dif);
}
// 주차 요금을 계산하기 위한 메서드
static void cul(int[] fees) {
for (String key : parseMap.keySet()) {
// 주차시간이 기본 시간보다 작다면
if (parseMap.get(key) < fees[0]) {
parseMap.put(key, fees[1]);
} else {
// 주차시간에서 기본시간 빼기
double addTime = parseMap.get(key) - fees[0];
// 단위 시간으로 나누고 올림처리
addTime = Math.ceil(addTime / fees[2]);
// 총 요금
int result = (int) (addTime * fees[3] + fees[1]);
// 요금 map에 업데이트
parseMap.put(key, result);
}
}
}
}
'코딩 테스트' 카테고리의 다른 글
(Java) 프로그래머스 - 두 큐 합 같게 만들기 (0) | 2022.09.01 |
---|---|
(Java) 프로그래머스 - k진수에서 소수 개수 구하기 (0) | 2022.08.31 |
(Java) 프로그래머스 - 양궁대회 (0) | 2022.08.26 |
(Java) 프로그래머스 - 성격 유형 검사하기 (0) | 2022.08.25 |
(Java) 프로그래머스 - 하노이의 탑 (0) | 2022.08.18 |