본문 바로가기

BAEKJOON/수학

백준 2108번 [통계학](C++)-yes6686- 티스토리

728x90
SMALL

백준 문제 풀이: 2108 [통계학]


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

문제 설명:

주어진 데이터들에 대해 다음의 네 가지 통계값을 구하는 문제입니다:

  • 1. 산술평균: 모든 데이터의 합을 데이터 개수로 나눈 값 (소수점 첫째 자리에서 반올림).
  • 2. 중앙값: 데이터들을 크기순으로 정렬했을 때 중앙에 위치한 값.
  • 3. 최빈값: 가장 많이 나타나는 데이터 값. 여러 개일 경우 두 번째로 작은 값을 선택.
  • 4. 범위: 데이터들 중 최대값과 최소값의 차이.

문제 해결 코드


#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int arr[500001];
int check[8001];

bool compare(int a, int b) {
    return a > b;
}

int main() {
    int n;
    cin >> n;
    int sum = 0;

    for (int i = 0; i < n; i++) {
        cin >> arr[i];
        sum += arr[i];
        check[arr[i] + 4000]++;
    }
    sort(arr, arr + n);
    
    // 1. 산술평균
    cout << fixed;
    cout.precision(0);
    cout << (int)round((double)sum / n) << endl;
    
    // 2. 중앙값
    cout << arr[(n - 1) / 2] << endl;
    
    // 3. 최빈값
    int index;
    int max = -1;
    for (int i = 0; i < 8001; i++) {
        if (max < check[i]) {
            max = check[i];
            index = i;
        }
    }
    for (int i = index + 1; i < 8001; i++) {
        if (max == check[i]) {
            index = i;
            break;
        }
    }
    cout << index - 4000 << endl;

    // 4. 범위
    cout << arr[n - 1] - arr[0] << endl;
}

코드 설명

  • 산술평균: 입력받은 데이터의 합을 데이터 개수로 나누어 계산하며, `round` 함수를 이용해 소수 첫째 자리에서 반올림합니다.
  • 중앙값: 데이터를 정렬한 뒤, 배열의 중간 인덱스 값을 출력합니다.
  • 최빈값:
    • `check` 배열을 이용해 값의 빈도를 저장합니다. 데이터 값의 범위는 -4000에서 4000이므로, 이를 0 ~ 8000의 인덱스로 매핑합니다.
    • 가장 높은 빈도를 가진 값 중 두 번째로 작은 값을 선택합니다.
  • 범위: 정렬된 배열의 마지막 값과 첫 번째 값의 차이를 출력합니다.

결과

주어진 데이터를 기준으로 산술평균, 중앙값, 최빈값, 범위를 차례대로 출력합니다. 최빈값 계산 시 두 번째로 작은 값을 선택하도록 구현했습니다.

추가적으로 더 효율적인 방법이나 코드에 대한 질문이 있다면 댓글로 알려주세요!

728x90
LIST