https://www.acmicpc.net/problem/21942
만약 벌금을 내야하는 사람들이 없는 경우는 -1을 출력한다.
문자열 파싱, Map
문자열 파싱과 Map을 통해 해결할 수 있다.
단순 구현이지만, 어떤 점을 주의해야할지 먼저 생각해보자.
- 출력은 사전순으로 정렬되어야 한다.
- 한 사람이 동시에 여러개의 부품을 대여할 수 있다.
- 한 사람이 한 번만 등장하지 않는다. <- 매우 중요.
이제 벌금 계산 방식을 생각해보자.
특정 단위시간으로 변경 후, 시간의 차를 구하면 벌금의 유무를 확인할 수 있다.
어떻게 문제를 단순화 할 수 있을지 생각해보자.
대여자와 대여부품 시간을 따로 관리하는것은 번거롭다.
대여자가 동시에 여러 부품을 빌릴 수 있기 때문이다.
그럼 Map에 Key로 대여물품과 대여자를 함께 엮어서 사용하면 어떨까.
그럼 정말 단순해진다.
각 대여자와 물품이 하나의 Key로 묶이게 되므로, 대여시간을 value로 Map에 저장하면 모든 조건을 만족시키며 하나의 Map으로 관리할 수 있다.
벌금 계산시에는 Key값을 다시 Tokenize 하여 대여자를 특정할 수 있다..!
코드를 참고해보자.
Java에서 TimeFormatter를 이용하여 쉽게 분 단위의 시간 차이를 구할 수 있다.
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.Map;
import java.util.TreeMap;
public class Main {
static int fine;
static long limitTime;
static Map<String, Long> personFineMap = new TreeMap<>();
static Map<String, String> personTimeMap = new HashMap<>();
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader((System.in)));
String[] inputs = in.readLine().split(" ");
int T = stoi(inputs[0]);
limitTime = getTimeLimit(inputs[1]);
fine = stoi(inputs[2]);
for (int tc = 0; tc < T; ++tc) {
inputs = in.readLine().split(" ");
String currentTime = inputs[0] + " " + inputs[1]; // YYYY-MM-DD hh:mm 구조
String key = inputs[2] + inputs[3]; // 대여물품과 대여자를 하나로 묶어서 생각한다.
if (personTimeMap.containsKey(key)) {
// 빌린 기록이 있다면 대여시간을 충족하는지 확인해보자
long total = getFine(personTimeMap.get(key), currentTime);
if (total > 0) // 벌금이 존재한다.
personFineMap.put(inputs[3], personFineMap.getOrDefault(inputs[3], 0L) + total);
personTimeMap.remove(key); // 같은 대여자가 같은 물품을 다시 빌리는 경우가 있다. 기존 값을 지우자.
} else {
personTimeMap.put(key, currentTime); // 최초로 빌리는 경우다.
}
}
if (personFineMap.isEmpty()) {
System.out.println(-1);
} else {
StringBuilder sb = new StringBuilder();
for (String key : personFineMap.keySet())
sb.append(key).append(" ").append(personFineMap.get(key)).append("\n");
System.out.println(sb);
}
}
private static long getFine(String startTime, String endTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dt1 = LocalDateTime.parse(startTime, formatter);
LocalDateTime dt2 = LocalDateTime.parse(endTime, formatter);
Duration duration = Duration.between(dt1, dt2);
long time = duration.getSeconds() / 60 - limitTime;
if (time > 0)
return time * fine;
return 0;
}
private static long getTimeLimit(String s) {
String[] tl = s.split("/");
String[] hhmm = tl[1].split(":");
return stoi(tl[0]) * 24 * 60 + stoi(hhmm[0]) * 60 + stoi(hhmm[1]);
}
private static int stoi(String s) {
return Integer.parseInt(s);
}
}