Backend
home
⚔️

[백준] 크로스컨트리

생성일
2025/02/09 06:15
태그
BaekJoon
게시일
2025/02/09
최종 편집 일시
2025/02/09 06:22

문제

해결 방안 고민

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을 여러 번 활용해야 한다는 점에서 로직이 꼬이거나 복잡해질 수 있기에 자료구조에 대한 활용법과 숙지가 많이 필요함을 느꼈다.