이번 문제는 꽤 오래 고민했다. 아니 고민했다기 보다 손을 대기가 쉽지 않았다.
지난번에 배웠던 배열 정렬을 잘 활용해야 이 문제가 풀릴 것 같았기 때문이다.
2108번) 통계학
최빈값을 제외하고는 어렵지 않은 문제이다. 다만, 중앙값과 범위를 쉽게 구하기 위해 Collections.sort()를 사용하여 정렬하였다.
최빈값을 구하는 방법은 최대범위가 +-4000이므로 arr[8001]를 선언하여 arr[입력값+4000]을 증가시키면 될 것이다.
문제는 동일한 빈도 수일때 2번째 값을 받아오는 것이었다.
해결방법은 의외로 간단했다. 배열에 값을 입력받을 때 최대 빈도 수를 먼저 측정하는 것이다.
나는 입력을 받은 후에 어찌할지 생각하다보니 이 부분을 놓친 것 같아 아쉬웠다.
그래도 오랜만에 혼자 문제를 해결하니 뭔가 개운했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] cnt = new int[8001]; // 실제로는 index - 4000
int max = 0;
double sum = 0;
int N = Integer.parseInt(br.readLine());
ArrayList<Integer> arr = new ArrayList<>(N);
for(int i = 0; i < 8001; i++) cnt[i] = 0;
for(int i = 0; i < N; i++){
int num = Integer.parseInt(br.readLine());
arr.add(num);
sum += num; // 산술평균에 쓰일 합
cnt[num+4000]++; // 배열에서 카운팅
if(cnt[num+4000] > max) max = cnt[num+4000]; // 최빈값에 쓰일 최대 빈도수
}
Collections.sort(arr);
// 출력부
System.out.println(Math.round(sum/N));
System.out.println(arr.get(N/2));
System.out.println(mode(max, cnt));
System.out.println(arr.get(N-1)-arr.get(0));
}
public static int mode(int max, int[] cnt){
int max_cnt = 0;
int ind = 0;
for(int i = 0; i < 8001; i++){
if(cnt[i] == max){
ind = i;
max_cnt++;
if(max_cnt == 2) break; // 빈도수가 같으면 밑에서부터 두번째에 멈춤
}
}
return ind - 4000;
}
}