[BAEKJOON] 백준 2108: 통계학(C#)

2024. 4. 12. 05:11IT/BaekJoon

문제 링크

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

 

2108번: 통계학

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

www.acmicpc.net

 

 

문제

수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.



입력

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

 

출력

첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.

둘째 줄에는 중앙값을 출력한다.

셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.

넷째 줄에는 범위를 출력한다.

 

 

 

통과한 답안

더보기
namespace _2108
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            int N = int.Parse(input);
            int[] arr = new int[N];
            Dictionary<int, int> frequency = new Dictionary<int, int>();

            for (int i = 0; i < N; i++)
            {
                input = Console.ReadLine(); 
                arr[i] = int.Parse(input);
                if (frequency.ContainsKey(arr[i]))
                {
                    frequency[arr[i]]++;
                }
                else
                {
                    frequency.Add(arr[i], 1);
                }
            }
            Array.Sort(arr);

            // 산술평균

            int mean = (int)Math.Round(arr.Average());
            Console.WriteLine(mean);

            // 중앙값

            int median = arr[N / 2];
            Console.WriteLine(median);

            // 최빈값

            int maxFrequency = frequency.Values.Max();
            var modes = frequency.Where(p => p.Value == maxFrequency)
                                 .Select(p => p.Key).OrderBy(p => p).ToList();
            int mode = modes.Count > 1 ? modes[1] : modes[0];
            Console.WriteLine(mode);

            // 범위

            int range = arr[N - 1] - arr[0];
            Console.WriteLine(range);
        }
    }
}

 

이 문제는 4가지 통계값을 구하는 문제로 중앙값과 범위의 경우에는

Array.Sort()함수를 이용하여 함수를 정렬하므로 쉽게 구할 수 있지만,

산술평균과 최빈값은 조금의 추가 처리가 필요하다.

 

산술평균의 경우에는 (int)arr.Average();의 평균을 구하는 함수로만 구한다면

주어진 조건인 소수점 이하 첫째 자리에서 반올림을 처리할 수 없으므로

(int)Math.Round(arr.Average())로 Math.Round 함수를 이용해야한다.

 

최빈값의 경우가 이번 문제의 포인트라고 할 수 있는데,

이를 구하기 위해서 Dictionary를 생성하고 숫자를 입력하는 과정에서

이 Dictionary의 해당하는 숫자의 출현 빈도를 저장한다.

그 후에 최빈값을 구하는 과정에서 Linq를 이용하여

가장 많이 등장하는 값들 중에서 이들을 숫자순으로 정렬한 뒤에

해당하는 최빈값의 수가 1개라면 그 값을 출력하고

1개보다 많다면 최빈값 중 두 번째로 작은 값(modes[1])을 출력하게 한다.