대표선수_2461
링크 : https://www.acmicpc.net/problem/2461
2461번: 대표 선수
입력의 첫 번째 줄에는 학급의 수를 나타내는 N과 각 학급의 학생의 수를 나타내는 M이 하나의 빈칸을 사이에 두고 주어진다. 단, 1 ≤ N, M ≤ 1,000이다. 두 번째 줄부터 N개의 줄에는 각 줄마다 한
www.acmicpc.net
문제 설명
학급의 수 N과 각 학급의 학생수 M이 주어지고
각 학생들은 능력치를 가지고있다.
학급마다 한 명씩 대표를 뽑아 경기를 치른다.
대표선수들의 능력치 중 최댓값과 최솟값의 차이를 구했을 때 최소의 차이를 만드는 대표선수를 뽑아야한다.
이때 차잇값을 구하는 문제이다.
문제 풀이
생각 과정
내가 생각한 방식은 학생들을 학급에 관계없이 모두 리스트에 넣고
능력치에 따라서 정렬을 해준다.
다음 투포인터를 활용하여 각 포인터사이에 모든 학급이 포함되도록 포인터위치를 설정한다.
해당 범위 내의 최솟값과 최댓값을 구해서 차이를 갱신해준다.
갱신 후 왼쪽 포인터를 한 칸 옮겨준다.
만약 모든 범위 내에 모든 학급이 포함되지 않았다면 오른쪽 포인터를 한 칸 옮겨준다.
구현
public class 대표선수_2461 {
static int N, M;
static int count[];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 학급 수
M = Integer.parseInt(st.nextToken()); // 학생 수
count = new int[N]; // 각 학급의 학생이 몇 명 사용됐는가
List<Student> students = new ArrayList<>();
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
students.add(new Student(i, Integer.parseInt(st.nextToken())));
}
}
Collections.sort(students); // 능력치로 정렬
int left = 0;
int right = 0;
int answer = Integer.MAX_VALUE;
while (left < N * M - 1 && right < N * M - 1) {
while (right < N * M - 1) { //모든 학급이 포함되도록 right 변경
count[students.get(right++).num]++;
if (check()) break;
}
while (count[students.get(left).num] > 1) { //모든 학급이 포함되도록 left 변경
count[students.get(left++).num]--;
}
if (check()) { //모든 학급 포함시 값 갱신
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = left; i < right; i++) {
min = Math.min(min, students.get(i).stat);
max = Math.max(max, students.get(i).stat);
}
answer = Math.min(answer, max - min);
}
count[students.get(left++).num]--; // left 변경
}
System.out.println(answer);
}
public static boolean check() { //모든 학급이 포함되었는지 확인하는 함수
for (int cnt : count) {
if (cnt == 0) return false;
}
return true;
}
static class Student implements Comparable<Student> {
int num;
int stat;
public Student(int num, int stat) {
this.num = num;
this.stat = stat;
}
@Override
public int compareTo(Student s) {
return this.stat - s.stat;
}
}
}
주의점
'공부 일지 > 문제풀이' 카테고리의 다른 글
[프로그래머스] 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기(MySQL) (0) | 2023.11.17 |
---|---|
[프로그래머스] 동명 동물 수 찾기(MySQL) (0) | 2023.11.15 |
[백준] 수들의 합 2 (JAVA) (1) | 2023.05.10 |
[백준] 배열 돌리기 4 (JAVA) (0) | 2023.05.09 |
[백준] 파이프 옮기기 (JAVA) (0) | 2023.05.09 |