알고리즘 풀이

[C#] 백준 2108번 문제풀이

bimtaeur30 2025. 10. 18. 18:50

안녕하세요.

오늘은 백준 2108번 '통계학' 문제풀이를 해보겠습니다

이번 통계학 문제는 숫자 N과 N만큼의 숫자들에 대한 산술평균, 중앙값, 최빈값, 범위값을 구하는 총 4파트로 이루어져있습니다.

 

입력예시

5 // 숫자 N
1
3
8
-2
2

 

출력예시

2
2
1
10

 

그럼 바로 문제풀이를 해보겠습니다.

우선 숫자 N을 받아오고 N만큼의 숫자들도 받아와 리스트에 저장합니다.

int n = int.Parse(Console.ReadLine()!);

List<int> numbers = new List<int>();

// N번 반복하여 숫자들을 입력받아 리스트에 추가
for (int i = 0; i < n; i++)
{
    numbers.Add(int.Parse(Console.ReadLine()!));
}

 

첫번째로 산술평균을 계산해보겠습니다.

값들의 평균을 구해주고 그 평균값에 대한 반올림을 진행합니다. 그리고 int로 강제형식변환을 해주면 정수로 변환됩니다.

산술평균을 출력해줍니다.

double average = numbers.Average();
int meanResult = (int)Math.Round(average);
Console.WriteLine(meanResult);

 

두번째로 중앙값을 계산해보겠습니다.

숫자들의 리스트를 정렬해주고, 리스트의 중간값 인덱스를 구해줍니다. n은 항상 홀수로 주어지기 때문에 잘못된 중앙값을 참조하지 않습니다.

중앙값을 출력해줍니다.

numbers.Sort();
int medianIndex = (numbers.Count - 1) / 2;
int medianResult = numbers[medianIndex];
Console.WriteLine(medianResult);

 

세번째로 최빈값을 계산해보겠습니다.

최빈값은 LINQ로 계산해야하는데 저는 LINQ에 미숙해서 이번 문제를 풀면서 가장 공부를 많이 해야했던 파트였습니다.

우선 숫자들에 GroupBy를 적용시켜줍니다.

GroupBy는 원본 리스트에서 3이라는 키를 가진 하나의 IGrouping<int, int>객체를 반환합니다. 예를들어볼 때 이 IGrouping객체는 Key로 숫자 3을 가지며, 내부적으로 {3, 3, 3}이라는 요소 컬렉션을 담고 있습니다.

Select는 IGrouping컬렉션을 받아서 Number와 Count 속성을 가진 새로운 익명 형식 객체를 만들고, 이 객체들의 컬렉션인 IEnumerable<T>을 반환합니다. 이 과정을 통해 데이터가 평탄화되어 정렬하기 쉬운 구조로 바뀝니다.

정렬을 해주고, List로 변환합니다.

Count가 같은 값이 여러 개 있을 때는 최빈값 중 두 번째로 작은 값을 출력해줍니다.

var frequencyList = numbers
    .GroupBy(x => x)
    .Select(g => new { Number = g.Key, Count = g.Count() })
    .OrderByDescending(g => g.Count)
    .ThenBy(g => g.Number)
    .ToList();

int modeResult;
if (frequencyList.Count > 1 && frequencyList[0].Count == frequencyList[1].Count)
{
    modeResult = frequencyList[1].Number;
}
else
{
    modeResult = frequencyList[0].Number;
}
Console.WriteLine(modeResult);

 

마지막으로 범위계산을 해보겠습니다.

간단하게 가장 큰 수, 작은 수를 더하여 빼줍니다.

범위값을 출력합니다.

int max = numbers.Max();
int min = numbers.Min();
int rangeResult = max - min;
Console.WriteLine(rangeResult);

 

이번 문제를 풀면서 LINQ를 손에 익도록 연습해야겠다는걸 깨닫게 되었습니다.

다음은 전체코드입니다.

감사합니다.

internal class Program
{
    static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine()!);

        List<int> numbers = new List<int>();

        // N번 반복하여 숫자들을 입력받아 리스트에 추가
        for (int i = 0; i < n; i++)
        {
            numbers.Add(int.Parse(Console.ReadLine()!));
        }

        //산술평균
        double average = numbers.Average();
        int meanResult = (int)Math.Round(average); // c#의 기본 반올림은 '은행반올림' 이다. 근데 반올림 한 수가 0.5일때 0에서 더 먼 쪽으로 반올림 하는것이 MidpointRounding.AwayFromZero이다.
        Console.WriteLine(meanResult);

        //중앙값 계산
        numbers.Sort();
        int medianIndex = (numbers.Count - 1) / 2;
        int medianResult = numbers[medianIndex];
        Console.WriteLine(medianResult);

        //최빈값 계산
        var frequencyList = numbers
            .GroupBy(x => x)
            .Select(g => new { Number = g.Key, Count = g.Count() })
            .OrderByDescending(g => g.Count)
            .ThenBy(g => g.Number)
            .ToList();

        int modeResult;
        if (frequencyList.Count > 1 && frequencyList[0].Count == frequencyList[1].Count)
        {
            modeResult = frequencyList[1].Number;
        }
        else
        {
            modeResult = frequencyList[0].Number;
        }
        Console.WriteLine(modeResult);

        
        //범위계산
        int max = numbers.Max();
        int min = numbers.Min();
        int rangeResult = max - min;
        Console.WriteLine(rangeResult);

    }
}

 

'알고리즘 풀이' 카테고리의 다른 글

[C#] 백준 2775번 문제풀이  (0) 2025.12.26
[C#] 백준 28702번 문제풀이  (0) 2025.10.19
[C#] 백준 1874번 풀이  (0) 2025.10.16
[C#] 백준 1966번 문제풀이  (0) 2025.10.12
[C#] 백준 1764번 문제풀이  (2) 2025.08.13