ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 2108] 통계학
    PS/C++ 2024. 6. 25.

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

     

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

    4개의 값을 출력해야 하는데 최빈값을 구할 때 최빈값이 여러 개 있을 때에는 최빈값 중에서 두 번째로 작은 값을 찾아야 한다

     

    평균 : N개의 수를 입력받으면서 모두 더해주고 N으로 나누면 된다. 이 때 더하는 수 sum은 double로 받거나 나눌 때 (double) 로 형 변환 해야 틀리지 않는다.

    범위 : 최소 ,최대는 min(a, b), max(a, b)를 이용한다

    중앙값 : counting 정렬을 이용한다. 수의 범위가 -4000 ~ 4000이니 count[k + 4000]으로 기수정렬 하고 N은 항상 홀수이니 중간에 오는 값은 항상 N / 2 + 1이다.count배열을 min + 4000 ~ max + 4000까지 돌면서 수의 갯수가 N / 2 + 1을 넘어가는 순간의 값에 - 4000을 한게 최빈값이다ex)N = 7-2 -1 -1 -1 0 2 3, 실제 중앙에 위치한 값 = -1

    -2 -1 0 2 3
    1 3 1 1 1

    sum(count[0] ~ count[k])가 N / 2 + 1이 넘어가는 순간 = -1

     

    최빈값: counting 정렬 시 최대 count 갯수를 미리 구해놓는다. k = -1로 두고 count[i] == 최대 count일 경우 정답에 k를 저장해놓고, count[i] == 최대 count && k != -1일경우 두 번째 최빈값이므로 갱신한다

     

    #include <bits/stdc++.h>
    using namespace std;
    int N, arr[8001];
    // FASTIO
    const int SIZE = 1 << 21;
    char buffer[SIZE];
    int idx;
    char read() {
        if(idx == SIZE) {
            int res = fread(buffer, sizeof(char), SIZE, stdin);
            if(res == -1){
                buffer[0] = -1;
            }
            idx = 0;
        }
        return buffer[idx++];
    }
    int nextInt() {
        int ret = 0;
        char c = read();
        while(c <= 32) {
            c = read();
        }
        bool neg = (c == '-' );
        if(neg) {
            c = read();
        }
        do {
            ret = (ret << 3) + (ret << 1) + (c & 15);
        } while ((c = read()) > 32);
        return neg ? ~ret + 1 : ret;
    }
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(nullptr); cout.tie(nullptr);
        N = nextInt();
        int mx = -987654321;
        int mn = 987654321;
        int sum = 0;
        int mode = 0;
        for(int i = 0; i < N; i++) {
            int k = nextInt();
            arr[k + 4000]++;
            mx = max(k, mx);
            mn = min(k, mn);
            sum += k;
            mode = max(arr[k + 4000], mode);
        }
        int k = N / 2 + 1;
        int mid = 0;
    
        for(int i = mn + 4000; i <= mx + 4000; i++) {   // 중앙값
            if(k - arr[i] <= 0) {
                mid = i - 4000;
                break;
            } else {
                k -= arr[i];
            }
        }
        int a = -1;
        for(int i = mn + 4000; i <= mx + 4000; i++) {   // 최빈값
            if(arr[i] == mode && a != -1) {
                a = i;
                break;
            } else if(arr[i] == mode) {
                a = i;
            }
        }
        cout << (int) round((double) sum / N) << '\n';
        cout << mid << '\n';
        cout << (a - 4000) << '\n';
        cout << (mx - mn) << '\n';
    }

     

     

    'PS > C++' 카테고리의 다른 글

    [백준 1707] 이분 그래프  (0) 2024.07.04
    [백준 9375] 패션왕 신해빈  (0) 2024.07.02
    [백준 1062] 가르침  (0) 2024.06.24
    [백준 14504] 수열과 쿼리 18  (0) 2024.06.20
    [백준 17410] 수열과 쿼리 1.5  (0) 2024.06.20

    댓글

Designed by Tistory.