[백준] 9017번 크로스 컨트리 JAVA (자바) 풀이
문제 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