✔ 난이도 - Silver 3
골 넣었을 때 판별 로직 돈다
- 넣기 직전까지 이기고 있던 팀에 현재시간 - 이전 골 넣은 시간(lastTime)만큼 시간 더해준다
- 그 이후에 골 넣은 팀에 점수++, lastTime을 현재시간으로 업데이트 해주기
즉, 이전 골이 들어온 시점부터 지금 골이 들어온 시점까지 누가 이기고 있었는지를 계산
- 루프에서는 골이 들어오는 순간만 처리하고, 경기가 끝나는 시점은 루프에서 한 번만 처리
그러려면 각 팀 별 몇점인지 기록해야하고(HashMap), 각 팀 별 누직 시간 기록(배열)
String.format("%02d:%02d", min, sec)을 사용해서 분이나 초가 한자리수면 앞에 0 붙이는거 처리
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
Map<Integer, Integer> winningTime = new HashMap<>();
winningTime.put(1, 0);
winningTime.put(2, 0);
int[] score = new int[3];
int lastTime = 0;
for (int i = 0; i < T; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
int team = Integer.parseInt(st.nextToken());
String[] timeArr = st.nextToken().split(":");
int minute = Integer.parseInt(timeArr[0]);
int second = Integer.parseInt(timeArr[1]);
int time = minute*60 + second;
// System.out.println(time);
if (score[1] > score[2]) winningTime.put(1, winningTime.get(1) + (time - lastTime));
else if (score[1] < score[2]) winningTime.put(2, winningTime.get(2) + (time - lastTime));
score[team]++;
lastTime = time;
}
if (score[1] > score[2]) winningTime.put(1, winningTime.get(1) + (48*60 - lastTime));
else if (score[1] < score[2]) winningTime.put(2, winningTime.get(2) + (48*60 - lastTime));
int team1 = winningTime.get(1);
int team2 = winningTime.get(2);
int minute1 = team1/60;
int second1 = team1%60;
int minute2 = team2/60;
int second2 = team2%60;
String team1Time = String.format("%02d:%02d", minute1, second1);
String team2Time = String.format("%02d:%02d", minute2, second2);
sb.append(team1Time).append("\n").append(team2Time);
System.out.println(sb);
}
}
아래는 좀 더 간단한 풀이
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int score1 = 0, score2 = 0;
int time1 = 0, time2 = 0;
int lastTime = 0; // 마지막으로 상황이 변한 시각
int endTime = 48 * 60; // 2880초
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int team = Integer.parseInt(st.nextToken());
String[] timeStr = st.nextToken().split(":");
int now = Integer.parseInt(timeStr[0]) * 60 + Integer.parseInt(timeStr[1]);
// "직전 골 시점 ~ 현재 골 시점"까지 누가 이기고 있었는지 계산해서 누적
if (score1 > score2) {
time1 += (now - lastTime);
} else if (score2 > score1) {
time2 += (now - lastTime);
}
// 스코어 업데이트 및 시점 갱신
if (team == 1) score1++;
else score2++;
lastTime = now;
}
// 마지막 골 이후부터 경기 종료(48분)까지의 시간 처리
if (score1 > score2) {
time1 += (endTime - lastTime);
} else if (score2 > score1) {
time2 += (endTime - lastTime);
}
// 결과 출력
System.out.println(formatTime(time1));
System.out.println(formatTime(time2));
}
// 시간 포맷팅 함수
private static String formatTime(int totalSeconds) {
int m = totalSeconds / 60;
int s = totalSeconds % 60;
return String.format("%02d:%02d", m, s);
}
}
O(N)
String.format("%02d:%02d", min, sec)
| 기호 | 설명 | 예시 |
|---|---|---|
| %d | 10진수 정수 (Decimal) | %d -> 10 |
| %s | 문자열 (String) | %s -> "Hello" |
| %f | 실수 (Floating point) | %f -> 3.141592 |
| %n | 줄바꿈 (Platform specific) | \n과 비슷하지만 시스템에 최적화됨 |
%02d: 정수를 출력하되 2자리를 채우고 빈 공간은 0으로 채움
int min = 1;
int sec = 5;
// "01:05" 출력
String time = String.format("%02d:%02d", min, sec);
double pi = 3.14159265;
// "3.14" (소수점 둘째 자리까지)
String result = String.format("%.2f", pi);
int money = 1000000;
// "1,000,000"
String result = String.format("%,d", money);
성능이 중요한 상황(수십만 번 호출 등)에서는 StringBuilder를 이용한 수동 패딩보다 약간 느릴 수 있다. 하지만 이 문제처럼 출력이 적은 경우에는 String.format을 사용하는 것도 좋은 방법이다.