경험의 기록

문제 : https://www.acmicpc.net/problem/2108

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

 
 

 

풀이

// [백준] 2108. 통계학 (Java)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

public class Main{
	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(in.readLine()); 
		int[] arr = new int[n]; // 숫자 저장할 배열
		int a = 0; // 산술평균
		int b = 0; // 중앙값
		int c = 0; // 최빈값
		int d = 0; // 범위
		
		// 숫자 입력
		for(int i=0;i<n;i++) {
			arr[i] = Integer.parseInt(in.readLine());
		}
		
		// 산술평균
		int sum = 0;
		for(int i=0;i<n;i++) {
			sum += arr[i];
		}
		a = (int)Math.round(((double)sum /n));
		
		// 중앙값
		Arrays.sort(arr);
		b = arr[n/2];

		// 최빈값
		int[] plus = new int[4002];
		int[] minus = new int[4001];
		for(int i=0;i<n;i++) {
			// 0 ~ 4000 빈도 저장
			if(arr[i] <0) {
				minus[Math.abs(arr[i])]++;
			}
			
			// -1 ~ -4000 빈도 저장
			else {
				plus[arr[i]]++;
			}
		}
		
		ArrayList<Integer> list = new ArrayList<>();
		
		// 가장 높은 빈도수 체크
		int max = 0;
		for(int i=0; i<plus.length;i++) {
			max = Math.max(max, plus[i]);
			
		}
		for(int i=0; i<minus.length;i++) {
			max = Math.max(max, minus[i]);
		}
		
		// 가장 빈도 높은 숫자들 따로 ArrayList에 담기
		for(int i : arr) {
			if(i<0) {
				if(minus[Math.abs(i)] == max && !(list.contains(i))) {
					list.add(i);
				}
			}
			else {
				if(plus[i] == max && !(list.contains(i))) {
					list.add(i);
				}
			}
		}
		
		// 2개 이상이면 2번째로 작은 것 출력
		if(list.size()>=2) {
			c = list.get(1);
		}
		// 1개면 그대로
		else {
			c = list.get(0);
		}
		
		// 범위
		d = arr[n-1] - arr[0];
		
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
		System.out.println(d);
		in.close();
	}
}

우선 산술 평균

문제에 나온대로 N개의 수의 합을 N으로 나눈 값의 반올림을 구하면 되고,

 

중앙값

N은 홀수라고 주어졌으므로

정렬 후 n/2 위치의 값을 구하면 된다.

 

범위

위에서 정렬했으니 인덱스 0 값, 마지막 인덱스 값을 빼면되는데

 

문제는 최빈값이다.

더 효율적인 방법이 있을 수 있으나 입력되는 정수의 범위는 -4000 ~ 4000 이라고 명시되어있기 때문에

그 모든 수의 빈도를 체크하는 방식으로 해결하였다.

plus 배열에는 0 ~ 4000을 저장해주고

minus 배열에는 -1 ~ -4000을 저장해준다.

 

그 후 배열을 순회하여 가장 높은 빈도수를 체크한다.

 

이제 빈도 높은 숫자들을 따로 ArrayList에 담고,

그 숫자가 2개 이상이라면 두번째로 작은 값을 출력해야 하므로 2번째 인덱스 값 (정렬되어있으므로),

1개라면 그냥 처음인덱스 값이 최빈값이다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading