🧪 2461 대표 선수
난이도 : 🌟 골드 2
유형 : 투포인터
https://www.acmicpc.net/problem/2461
📝 문제

KOI 중학교에는 N개의 학급이 있으며, 각 학급의 학생 수는 모두 M명으로 구성된다. 이 중학교에서는 체육대회에 새로운 종목의 경기를 추가하였다. 이 경기에 대해 모든 학생들은 저마다의 능력을 나타내는 능력치를 가지고 있으며, 이 능력치는 모든 학생이 서로 다르다.
이 경기는 한반에서 한 명의 대표선수를 선발하여 치른다. 경기의 형평성을 위하여, 각각의 반에서 대표로 선발된 모든 학생들의 능력치 중 최댓값과 최솟값의 차이가 최소가 되도록 선수를 선발하려고 한다. 예를 들어, N=3, M=4인 경우 학생들의 능력치가 1반=[12, 16, 67, 43], 2반=[7, 17, 68, 48], 3반=[14, 15, 77, 54]로 주어질 때, 각 학급으로부터 능력치 16, 17, 15를 가진 학생을 각각 선택하면, 최댓값과 최솟값의 차이가 17-15=2로 최소가 된다.
대표로 선발된 모든 학생들 능력치의 최댓값과 최솟값 차이가 최소가 되는 경우의 값을 출력하는 프로그램을 작성하시오.
입력
입력의 첫 번째 줄에는 학급의 수를 나타내는 N과 각 학급의 학생의 수를 나타내는 M이 하나의 빈칸을 사이에 두고 주어진다. 단, 1 ≤ N, M ≤ 1,000이다. 두 번째 줄부터 N개의 줄에는 각 줄마다 한 학급 학생들의 능력치를 나타내는 M개의 양의 정수가 하나의 빈칸을 사이에 두고 주어진다. 능력치는 0이상 109이하이다.
출력
대표로 선발된 모든 학생들 능력치의 최댓값과 최솟값 차이가 최소가 되는 경우의 값을 하나의 정수로 출력한다.
🧐 핵심 로직
1. 학생들의 성적 데이터를 이용해 주어진 조건을 만족하는 최소 점수 차이를 계산한다.
2. 프로그램은 입력 데이터를 처리하여 학생들의 성적을 저장하고, 이를 기반으로 최소 점수 차이를 찾는 알고리즘을 실행한다.
2 - 1) 첫 번째 줄에서 n(학생의 수)과 m(각 학생의 점수 개수)을 읽어온다.
2 - 2) 이후 학생들의 성적 데이터를 2차원 배열 students에 저장한다.
3. 각 학생의 점수를 오름차순으로 정렬한 뒤, 모든 학생의 현재 최소 점수를 추적하기 위해 indexes 배열을 초기화한다.
4. 최소 점수 차이를 계산하기 위해 아래의 단계를 반복한다.
4 - 1) 현재 각 학생의 최소 점수 중 가장 작은 값(minScore)과 가장 큰 값(maxScore)을 찾는다.
4 - 2) maxScore - minScore가 현재 저장된 최소 점수 차이(res)보다 작으면 res를 갱신한다.
4 - 3) minScore를 제공하는 학생의 점수를 다음 점수로 갱신하기 위해 해당 학생의 indexes 값을 증가시킨다.
4 - 4) 만약 특정 학생의 점수가 모두 처리되었다면 반복을 종료한다.
5. 계산된 최소 점수 차이를 출력한다.
💻 최종 코드 (2680 ms)
`java
import java.util.*;
import java.io.*;
public class Main {
static BufferedReader br;
static int n, m, res;
static int[] indexes;
static int[][] students;
public static void main(String[] args) throws Exception {
// br = new BufferedReader(new InputStreamReader(System.in));
br = new BufferedReader(new FileReader("input.txt"));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
res = Integer.MAX_VALUE;
fillBoard();
makeIndexArray();
selectPlayer();
System.out.println(res);
br.close();
}
private static void fillBoard() throws Exception {
students = new int[n][m];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
students[i][j] = Integer.parseInt(st.nextToken());
}
}
}
private static void makeIndexArray() {
indexes = new int[n];
for (int i = 0; i < n; i++) {
Arrays.sort(students[i]);
indexes[i] = 0;
}
}
private static void selectPlayer() {
while (true) {
int minScore = students[0][indexes[0]];
int maxScore = students[0][indexes[0]];
int minIdx = 0;
for (int i = 1; i < n; i++) {
if (minScore > students[i][indexes[i]]) {
minScore = students[i][indexes[i]];
minIdx = i;
}
if (maxScore < students[i][indexes[i]]) {
maxScore = students[i][indexes[i]];
}
}
if (maxScore - minScore < res) {
res = maxScore - minScore;
}
if (++indexes[minIdx] >= m) break;
}
}
}
`
'Hub Algorithm > 투포인터' 카테고리의 다른 글
[BOJ] 백준 15961 : 회전 초밥 (java) (0) | 2025.01.30 |
---|---|
[BOJ] 백준 2283 : 구간 자르기 (java) (1) | 2025.01.29 |
[BOJ] 백준 13422 : 도둑 (java) (1) | 2024.12.08 |
[BOJ] 백준 20366 : 같이 눈사람 만들래? (java) (0) | 2024.11.20 |
[BOJ] 백준 25395 : 커넥티드 카 실험 (java) (2) | 2024.10.15 |