문제 이해
조건
문제에서 주어진 조건을 잘못 이해하고 넘어가는 경우 코드를 다르게 작성할 수 있으니 초기에 조건을 정확하게 이해하자
1. 차량은 In Out을 여러번 할 수 있음
00~23:59 동안의 해당 차량번호가 얼마나 주차장에 머물렀는지 체크
들어갈때마다 기본 주차요금이 계속 더해지는게 아니라 하루동안에 머물렀던 총 시간을 기준으로 계산
로직
전체 로직을 세분화시키고 세분화된 로직별로 처리하면서 진행하자
0.초기값 세팅
Map<String(차량번호),Integer(입차시간)> in
Map<String(차량번호),Integer(경과시간)> out
List<Record> record(차량별 요금 기록)
1.IN 차량이 있으면 시간체크 시작 (O)
-> 입차시간 저장, 처음 In인 경우 경과시간 0으로 초기화
2.OUT 차량이 있으면 경과시간 계산 (O)
-> in에 해당 차량의 입차시간을 -1 처리(in~out이 한세트로 되었다는 의미)
요금을 맨 마지막에 계산하는 이유는 해당 차량이 여러번 출차할 수도 있기 때문
3.모든 records를 뒤졌는데 IN하고 OUT하지 않은 차량이 있으면 23:59 출차로 간주 (O)
-> IN 이후에 OUT하지 않는 차량을 체크하는 방법
입차시간이 -1이 아닌 차량이 있으면 OUT하지 않은 차량으로 체크 후 요금 계산해서 record에 저장
4.record에 있는 차량을 번호가 작은 순서대로 정렬 후 answer에 저장
Java 코드
import java.util.*;
public class Main {
// carNum으로 정렬 후 fee를 출력하기 위한 클래스 선언
static class Record implements Comparable<Record> {
String carNum;
int fee;
@Override
public int compareTo(Record r) {
return this.carNum.compareTo(r.carNum);
}
}
static public int[] solution(int[] fees, String[] records) {
Map<String, Integer> in = new HashMap<String, Integer>();
Map<String, Integer> out = new HashMap<String, Integer>();
int recordCnt = records.length;
for (int i = 0; i < recordCnt; i++) {
if (records[i].substring(11).equals("IN")) {
// 입차시간 -> 분으로 변경
int startTime = Integer.parseInt(records[i].substring(0, 2)) * 60 + Integer.parseInt(records[i].substring(3, 5));
String carNum = records[i].substring(6, 10);
in.put(carNum, startTime);
// 처음 입차인 경우 경과시간 0으로 세팅(두번째 입차부터 계속 더해져야 됨)
if(out.get(carNum) == null) {
out.put(carNum, 0);
}
} else if (records[i].substring(11).equals("OUT")) {
String carNum = records[i].substring(6, 10);
int endTime = Integer.parseInt(records[i].substring(0, 2)) * 60 + Integer.parseInt(records[i].substring(3, 5));
int totalTime = endTime - in.get(carNum);
if(out.get(carNum) != null) {
totalTime += out.get(carNum);
}
in.put(carNum, -1);
out.put(carNum, totalTime);
}
}
// 차량별 최종 요금 계산
List<Record> record = new ArrayList<Record>();
for(Map.Entry<String, Integer> map : out.entrySet()){
String carNum = map.getKey();
int totalTime = map.getValue();
// In 이후 Out이 없는 차량은 추가적인 시간 계산
if(in.get(carNum) != -1){
totalTime += ((23 * 60 + 59) - in.get(carNum));
}
// 차량별 총 요금 계산
int totalFee = fees[1];
if (totalTime > fees[0]) { // 기본시간을 넘는 경우 추가요금 계산
// int와 int형의 나눗셈을 할 때 소수점이 나오면 정수형으로 리턴하기 때문에 소수부분이 잘라진다. 그러므로 한쪽을 double or float 같은 소수 타입의 숫자를 사용해야 한다.
totalFee = fees[1] + ((int) Math.ceil((double)(totalTime - fees[0]) / fees[2])) * fees[3];
}
Record r = new Record();
r.carNum = carNum;
r.fee = totalFee;
record.add(r);
}
Collections.sort(record);
int[] answer = new int[record.size()];
for(int i=0;i<record.size();i++){
answer[i] = record.get(i).fee;
}
return answer;
}
public static void main(String[] args) {
int[] fees = {180, 5000, 10, 600};
String[] records = {"05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"};
int[] answer = solution(fees, records);
for(int i=0;i<answer.length;i++){
System.out.print(answer[i] + " ");
}
}
}
'알고리즘&자료구조 > ETC' 카테고리의 다른 글
백준 - 15683 (1) | 2024.06.07 |
---|---|
프로그래머스 - k진수에서 소수 개수 구하기 (1) | 2024.06.06 |
프로그래머스 - 바탕화면 정리 (0) | 2024.06.03 |