💡 문제
💬 입출력 예시
📌 풀이(소스코드)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int N = Integer.parseInt(input[0]);
int F = Integer.parseInt(input[2]);
String[] date = input[1].split("/");
String[] time = date[1].split(":");
int limitDay = Integer.parseInt(date[0]);
int limitHour = Integer.parseInt(time[0]);
int limitMinute = Integer.parseInt(time[1]);
long limitTime = limitDay * 24L * 60L + limitHour * 60L + limitMinute;
HashMap<String, String> rentalMap = new HashMap<>();
TreeMap<String, Long> fineMap = new TreeMap<>();
for (int i = 0; i < N; i++) {
input = br.readLine().split(" ");
String value = input[0] + " " + input[1];
String key = input[2] + input[3];
if (rentalMap.containsKey(key)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime startTime = LocalDateTime.parse(rentalMap.get(key), formatter);
LocalDateTime endTime = LocalDateTime.parse(value, formatter);
Duration duration = Duration.between(startTime, endTime);
long delayTime = duration.getSeconds() / 60 - limitTime;
if (delayTime > 0) {
long totalFine = delayTime * F;
if (totalFine > 0) {
fineMap.put(input[3], fineMap.getOrDefault(input[3], 0L) + totalFine);
}
}
rentalMap.remove(key);
} else {
rentalMap.put(key, value);
}
}
if (fineMap.isEmpty()) {
System.out.println(-1);
return;
}
StringBuilder sb = new StringBuilder();
for (String key : fineMap.keySet()) {
sb.append(key).append(" ").append(fineMap.get(key)).append("\n");
}
System.out.println(sb);
}
}
📄 해설
접근
- 시간 관련 라이브러리를 잘 활용해야하는 문제. 작성자는 해당 라이브러리를 많이 사용해보질 않아, 다른 풀이를 확인하고 풀었다. 나중에 다시 풀어봐야할 문제다.
- 대여장을 표현하기 위해 Key 가 회원, 부품이고 Value 가 일자 및 시간인
HashMap
을 사용하고, 이름순으로 정렬된 벌금 장부를 표현하기 위해 Key 가 회원이고 Value 가 벌금인 TreeMap
을 사용한다.
- 대여장에 이미 대여 내역이 있는 경우 벌금을 계산하고 대여장에서 해당 내역을 제거하고, 없는 경우 그냥 대여장에 추가한다.
과정
- 입력 받은 문자열을 파싱해서 대여 기간을 구한다.
- 이후 N개의 입력을 받으면서, 입력 받은 문자열을 파싱해서 대여장을 표현하는
rentalMap
에 파싱해서 만든 Key 가 이미 존재하는 경우와 그렇지 않은 경우로 처리가 나뉜다.
- 이미 대여장에 현재 입력받은 회원과 부품이 Key로 존재하는 경우,
rentalMap
에 저장된 일자 및 시간과 현재 입력 받은 일자 및 시간과의 차이를 계산하고, 연체한 경우 벌금을 계산해서 fineMap
에 벌금을 추가한다. 그 다음 같은 물건은 중복 대여가 불가능 하므로, rentalMap
에서 해당 회원과 부품을 제거한다.
- 대여장에 현재 입력 받은 회원과 부품이 존재하지 않는 경우, 단순히
rentalMap
에 추가한다.
- 벌금을 저장하고 있는
fineMap
이 비어있지 않은 경우 -1을 출력하고, 그렇지 않으면 fineMap
에 존재하는 모든 회원의 벌금을 함께 출력한다. 이때, TreeMap
이므로 이미 이름 순으로 정렬이 되어있다.