본문 바로가기
Baekjoon/[7] 기타

[백준] 9017번 크로스 컨트리 JAVA (자바) 풀이

by Poorm 푸름 2024. 1. 29.
 

문제 9017 (구현)

  • 팀 = 6명이어야 점수 계산 가능 (6명 아래는 점수 없음)
  • 결승점을 통과한 순서대로 점수 부여 (점수는 등수와 같다)
  • 선수들의 소속 팀 번호 부여
  • 팀 점수 = 상위 4명의 주자의 점수를 합하여 계산 (결승점을 통과한 순서대로 점수를 받기)
  • 가장 낮은 점수를 얻는 팀이 우승 (동점의 경우, 다섯 번째 주자가 가장 빨리 들어온 팀이 우승)

  (예시)

 

→ 팀 B, D = 선수미달 = 점수 없음

 

팀 A 점수 = 18 (1+4+6+7)

                                                         ▶ 두 팀의 점수가 같으므로 5번째 선수 점수를 통해 A 팀 우승!!
팀 C 점수 = 18 (2+3+5+8)

 

[입력]

 

 :  첫 번째 줄 테스트 케이스 수 T (입력 데이터는 표준입력 사용)

 
 : 
각 테스트 케이스의 첫 번째 줄에 결승점 통과한 인원수  N (6 ≤ N ≤ 1,000)
    각 테스트 케이스의 두 번째 줄에는 등수 별로 팀 번호 나열

 

2
15
1 2 3 3 1 3 2 4 1 1 3 1 3 3 1
18
1 2 3 1 2 3 1 2 3 3 3 3 2 2 2 1 1 1

 

 

 [출력]


 : 
하나의 테스트 케이스에 대한 우승팀의 번호를 한 줄에 출력 (출력은 표준출력 사용)

 

1
3

 

 

 [문제접근]

    • 6명 미만 인원수부터 파악
      • teamNum[i] = team 
      • 결승점을 통과한 선수들의 팀번호를 입력받기
      • count[team]++
      • 팀번호를 인덱스로 뽑아서 팀번호 카운트
                
    • 통과한 팀 따로 분류
      •  if (count[team] < 6)  인원수 조건
      •  passTeam[team]++ 통과팀만 인원 수 추가

    • 단! 4인일 때 멈추기 (이미 count로 6이상인 건 확인했으니 계산을 위해서 4인까지만)
      •  if (passTeam[team] <= 4)
      •  score[team] += j 로 점수 저장
      • 이때 j는  j++로 밑에서 순차적으로 카운트 되고 그걸 입력하기 때문에 등수로 생각하면 된다
      • 이렇게되면 모든 통과팀이 상위 4번째까지만 입력이 된다

    • 동점일 경우를 대비해 5위까지 계산해보기
      • if (passTeam[team] == 5)
      •  score[team] += j; 

    • 팀점수 계산
      • minscore 초기값보다 계산된 점수가 더 작으면 minscore을 현재 팀점수로 갱신
      • 팀점수의 인덱스 = 팀번호이므로 해당 팀번호를 minteam 으로 지정

     

 

 [코드]

import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader (new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine()), i, n, team,j;
        StringTokenizer st;
        while (T-->0){
            n = Integer.parseInt(br.readLine()); 
            int count[] = new int[202]; 
            int teamNum[] = new int[n]; 
            st = new StringTokenizer(br.readLine());
            for (i = 0; i < n; i++){
                teamNum[i] = team = Integer.parseInt(st.nextToken()); 
                count[team]++; 
            }
            int score[] = new int[202]; 

            int passTeam[] = new int[202]; 
            int minscore = 1<<30, minteam = -1;
            
            for (i = 0, j=1; i < n; i++){
                team = teamNum[i]; 
                if (count[team] < 6) 
                    continue;
                passTeam[team]++;
                if (passTeam[team] <= 4)
                    score[team] += j << 19; 
                if (passTeam[team] == 5){
                    score[team] += j; 
                    if (score[team] < minscore){ 
                        minscore = score[team];
                        minteam = team;
                    }
                }
                j++;
            }
            System.out.println(minteam); 
        }
    }
}

 

 [해설]
     

 :  int T = Integer.parseInt(br.readLine()), i, n, team,j; 변수 설정
   

 :  while (T-->0){  테스트 케이스 만큼 반복
        n = Integer.parseInt(br.readLine());  각 테스트케이스의 첫째줄 입력
        int count[] = new int[202];  인원수 파악
        int teamNum[] = new int[n];  각 테스트케이스의 둘째줄 입력 (각 선수의 팀 번호)
     

        st = new StringTokenizer(br.readLine());
        for (i = 0; i < n; i++){
              teamNum[i] = team = Integer.parseInt(st.nextToken());  팀번호를 그냥 객체 / 배열 둘 다에 저장
              count[team]++;  팀번호 별 인원수 파악을 위해서 팀번호를 인덱스로 저장해서 카운트
        }
        

        int score[] = new int[202];  점수 저장
        int passTeam[] = new int[202];  6명이상인 팀 인원수 저장을 위해(= 통과한 팀)
        int minscore = 1<<30, minteam = -1;
            
        for (i = 0, j=1; i < n; i++){  다시한번 계산 점수 땜에
              team = teamNum[i];
       
      if (count[team] < 6)  인원수가 6아래면 계산에서 제외
                    continue;
              passTeam[team]++;  인원수 6인 팀만 인원수 추가
              if (passTeam[team] <= 4)  팀번호별 인원수 4까지만 점수 계산
                    score[team] += j << 19;  팀별 점수에 등수 갱신하기
              if (passTeam[team] == 5){  인원수 5일때도 추가로 계산해놓기
                    score[team] += j;  팀별 점수에 등수 계산
                    if (score[team] < minscore){  계산된 팀 점수가 이전보다 작다면
                        minscore = score[team];  결과는 팀점수 갱신
                        minteam = team;  결과는 해당팀이 된다 
                    }
              }
              j++;
        }
        System.out.println(minteam);  최소 점수를 가진 팀 출력
     }



 

 

이제 풀어보러 갈께요 :)



* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *

 

 

 

9017번: 크로스 컨트리

입력 데이터는 표준입력을 사용한다. 입력은 T 개의 테스트 케이스로 주어진다. 입력 파일의 첫 번째 줄에 테스트 케이스의 수를 나타내는 정수 T 가 주어진다. 두 번째 줄부터는 두 줄에 하나의

www.acmicpc.net