백준 문제풀이/기본수학2

2108. 통계학 (자바, Java)

뮤츠 2022. 9. 25. 20:46

 

다른건 쉬웠는데, 최빈값이 살짝 까다로웠습니다. 이전에 소수구하는 알고리즘에서 힌트를 얻었고, N 범위대비 입력되는 수의 값의 범위에서 재차 힌트를 얻었습니다. N은 50만개나 되지만, 입력되는 값의 절댓값은 4000을 넘지않아 꽤 좁은 편입니다.

그걸 이용해서, 숫자만큼의 boolean 배열을 만들어 소수여부를 판단하던 생각이 나 응용하였습니다.

단, -4000~4000이므로, 총 8001개의 숫자가 있다는걸 잊으면 안됩니다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Main {

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		int[] arr = new int[n];
		int max = -4000;
		int min = 4000;
		double sum = 0;
		
		for (int i=0; i<n; i++) {
			arr[i] = Integer.parseInt(br.readLine());
		}
		
		for (int i=0; i<n; i++) {
			if (max<arr[i]) {
				max = arr[i];
			}
			
			if (min>arr[i]) {
				min = arr[i];
			}
			
			sum += arr[i];
		}
		
		System.out.println(Math.round(sum/n));
		
		int[] result = new int[arr.length];
		int[] ct = new int[8001]; // -4000부터 4000까지 각 값의 등장횟수를 카운트
		
		for (int i=0; i<ct.length; i++) {
			
			for (int j=0; j<arr.length; j++) {				
				if (arr[j] == i-4000) {
					ct[i]++;					
				}				
			}			
		} // 최빈값은 누적하기 전에 출력해야함.
		
		int ctmax = 0;
		ArrayList<Integer> freq = new ArrayList<>();
		
		for (int i=0; i<ct.length; i++) {
			if (ctmax < ct[i]) {
				ctmax = ct[i];
			}
		}
		
		for (int i=0; i<ct.length; i++) {
			if (ctmax == ct[i]) {
				freq.add(i-4000);
			}
		} // 출력 순서를 지키기 위해, 값만 확보한뒤 출력은 뒤에 진행.		
		
		for (int i=1; i<ct.length; i++) {
			
			ct[i] += ct[i-1];
			
		} // 누적횟수로 정렬시 첫 등장순번을 알려줌
		
		for (int i=result.length-1; i>=0; i--) {
			int value = arr[i];
			ct[value+4000]--;
			result[ct[value+4000]] = value;
			
		}
		
		System.out.println(result[n/2]);
		
		if (freq.size()>=2) {
			System.out.println(freq.get(1));
		} else {
			System.out.println(freq.get(0));
		}
		
		System.out.println(max - min);

	}

}