문제
해결 방안 고민
•
Map 자료구조를 활용하여 구현을 하려고 하였으나 생각보다 구현 과정이 복잡하게 느껴져서 진행이 어려웠던 문제였다.
- 경주코스 : 4 ~ 12km
- 주자들의 개인성적으로 팀의 점수를 계산
- 한 팀은 여섯 명의 선수로 구성
- 팀 점수: 상위 4명의 주자 점수를 합하여 계산 (정렬?!)
- 점수는 자격을 갖춘 팀의 주자들에게만 주어짐
- 결승점을 통과한 순서대로 점수 받음 (일반적인 평가)
- 점수를 더하여 가장 낮은 점수를 얻는 팀이 우승을 함 (낮은 점수 팀이 우승팀)
- 여섯 명의 주자가 참가하지 못한 팀은 점수 계산에서 제외됨
- 동점의 경우에는 **다섯 번째 주자**가 가장 빨리 들어온 팀이 우승
===
1. 배열의 요소가 점수임 => 배열의 요소는 0부터 시작하므로 1로 설정하여 점수 계산을 진행
2. 여섯 명의 선수가 아닌 팀은 점수 계산에서 제외
1. 배열 요소 카운트를 할 때 무시하고 다음 단계로 진행
Markdown
복사
해결 방법
•
여러 상황을 고려한 배열과 변수를 각각 선언해줘야 한다.
◦
등수 저장용 int 배열 - ranks
◦
각 팀별 인원 수 저장용 Map - cntMap
◦
가장 큰 숫자의 팀 번호 저장용 int 변수
◦
해당 팀의 5번째 선수 저장용 배열 - fifth
◦
팀별 최종 점수 저장용 Map - scoreMap
◦
6명 이상인 팀별로 몇 명 있는지에 대한 저장용 Map - tmpMap
◦
가장 낮은 점수 저장용 int형 변수 - result
◦
5번째 점수 저장용 int형 변수 - fifthScore
•
조건들을 고려하여 문제풀이를 해야하는 데 이 부분이 만만치가 않다.
◦
한 팀은 6명의 선수로 구성 ⇒ scoreMap 선언
◦
6명의 선수가 아닌 팀은 점수 계산에서 제외됨
◦
점수를 더하여 가장 낮은 점수를 얻는 팀이 최종 우승
◦
만약에 동점인 팀이 존재하는 경우 다섯 번째 주자가 가장 빨리 들어온 팀이 최종 우승
코드
package algo250209;
import java.io.*;
import java.util.*;
// 크로스 컨트리 - 실버 3
/*
등수 저장용 int 배열 (ranks)
각 팀별 인원 수 저장용 Map (cntMap)
가장 큰 숫자의 팀 번호 저장용 int 변수
해당 팀의 5번째 선수 저장용 배열 (fifth)
팀별 최종 점수 저장용 Map (scoreMap)
6명 이상인 팀 별로 몇 명 있는지에 대한 저장용 Map (tmpMap)
가장 낮은 점수 저장용 int형 변수 (result)
5번째 점수 저장용 int형 변수 (fifthScore)
*/
public class Baek9017 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(br.readLine());
int[] answer = new int[T];
// 테스트 케이스 입력
// 1 2 3 3 1 3 2 4 1 1 3 1 3 3 1
for (int i = 0; i < T; i++) {
int N = Integer.parseInt(br.readLine());
int[] ranks = new int[N]; // N등까지 존재
Map<Integer, Integer> cntMap = new HashMap<>();
int teamNum = Integer.MIN_VALUE; // 가장 큰 번호의 팀
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
int value = Integer.parseInt(st.nextToken());
// cntMap에 각 팀별 번호와 번호 수 추가
cntMap.put(value, cntMap.getOrDefault(value, 0) + 1);
ranks[j] = value;
teamNum = Math.max(teamNum, value);
}
int[] fifth = new int[teamNum + 1]; // 해당 팀의 5번째 선수 저장용 배열
Map<Integer, Integer> scoreMap = new HashMap<>();
Map<Integer, Integer> tmpMap = new HashMap<>(); // 팀별로 누적하여 점수 계산
int score = 1;
for (int r : ranks) {
if (cntMap.get(r) == 6) { // 팀원이 6명인 경우에만
tmpMap.put(r, tmpMap.getOrDefault(r, 0) + 1);
if (tmpMap.get(r) <= 4) { // 해당 팀의 4등까지만 점수 기록
scoreMap.put(r, scoreMap.getOrDefault(r, 0) + score);
}
if (tmpMap.get(r) == 5) { // 해당 팀의 5번째 선수의 점수
fifth[r] = score;
}
score++;
}
}
int result = Integer.MAX_VALUE; // 가장 낮은 점수
int fifthScore = Integer.MAX_VALUE; // 5번째 점수
for (Integer key : scoreMap.keySet()) {
int tmp = scoreMap.get(key);
if (tmp < result) { // 점수가 가장 낮은 팀이 우승
result = tmp;
fifthScore = fifth[key];
answer[i] = key;
} else if (tmp == result) { // 점수가 동점일 경우, 5번째 선수의 점수가 낮은 팀이 우승
if (fifthScore > fifth[key]) {
answer[i] = key;
}
}
}
}
// 출력
for (int value : answer) {
bw.write(value + "\n");
}
bw.flush();
bw.close();
br.close();
}
}
Java
복사
느낀 점
구현을 한다는 게 생각보다 쉽지 않았다. 특히 이번 문제 같은 경우 map을 여러 번 활용해야 한다는 점에서 로직이 꼬이거나 복잡해질 수 있기에 자료구조에 대한 활용법과 숙지가 많이 필요함을 느꼈다.