ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2108 (통계학) c++
    백준 문제 2022. 7. 19. 20:13
    728x90

    문제

     

    2108번: 통계학

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

    www.acmicpc.net

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

    N이 주어지고 N개의 수를 입력하면 위의 4가지를 모두 구하는 것입니다.

    N은 무조건 홀수로 주어집니다.

     

    1) 산술평균은 먼저 모든 N개의 수의 합을 구해야 하므로 처음에 입력 받을 때 부터 

    sum 이라는 int형 변수에 누적으로 더해주었습니다.

    문제에서 소수점 아래 첫째 자리에서 반올림을 해줘야 하므로 round함수를 이용했습니다.

    소수점을 다뤄줘야 하므로 나눌 때  double형으로 캐스팅 해주고 

    이를 round함수의 인자로 넣어 주면서 다시 int형으로 캐스팅 해주었습니다.

    cout << (int)round((double)(sum)/n) << '\n';

     

    2) 중앙값은 먼저 N개의 수를 벡터에 넣어 오름차순으로 정렬한뒤

    [N/2] 번째 인덱스 값을 출력해 주면 됩니다.

    N은 무조건 홀수로 들어오기 때문입니다.

    cout << v[n/2] << '\n';

     

    3) 이 문제의 핵심 부분입니다.

    최빈값은 말 그대로 가장 많이 등장한 숫자를 말합니다.

    N의 범위가 50만 이기 때문에 2차원 반복문을 돌게 되면 시간초과가 일어납니다.

    또한 최빈값이 여러개일 경우 2번째로 작은 값을 구해야 합니다.

    수의 범위는 -4000 ~ 4000 입니다.

    음수는 배열의 인덱스로 저장 할 수 없습니다.

    어차피 범위가 4000까지 이므로 배열의 인덱스를 8000까지 잡으면 해결할 수 있습니다.

    ex) 만약 -8으로 배열로 표현하고 싶으면 arr[-8 + 4000]을 이용해 음수를 표현할 수 있습니다.

    먼저 처음에 N개의 수를 입력받을 때 작업해줍니다.

    위와 같이 arr배열에 값이 들어왔다는 값을 세어주는 것입니다.

    이제 최빈값을 세어주는 부분입니다.

    0부터 8000까지 돌면서 가장 최빈값을 갱신해주는 것입니다.

    이 떄 최빈값이 복수개이면 2번째로 작은 값을 구해줘야 하므로 boolean 형 변수를 둬서 

    맨 처음에 최빈값이 들어오게 되면 가장 작은 값이고 

    그 다음에 똑같은 최빈값이 들어오면 2번째로 작은 값이 므로 최빈값을 다시 갱신해주고 boolean 형 변수를 true로

    바꾸어 이제 갱신할 수 없도록 만듭니다.

    cout << ans << '\n';

     

    4) 범위는 아까 벡터를 정렬해주었으므로 가장 작은 값은 v[0]일 것이고 가장 큰 값은 v[N-1]일 것입니다.

    cout << v[n - 1] - v[0] << '\n';

    전체 코드입니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <cmath>
    #include <map>
    #include <set>
    #include <tuple>
    #define MAX 2100000000
    #define inf LONG_MAX
    using namespace std;
    using ll = long long;
    using ull = unsigned long long;
    vector<int>v;
    int arr[8001];
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
        int n;
        cin >> n;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            int a;
            cin >> a;
            sum += a;
            v.push_back(a);
            arr[a + 4000]++;
        }
        sort(v.begin(), v.end());
        
        int cnt_max = 0;
        int ans;
        bool check = false;
        for (int i = 0; i < 8001; i++) {
            if (arr[i] == 0)
                continue;
            if (cnt_max < arr[i]) {
                check = false;
                cnt_max = arr[i];
                ans = i-4000;
            }
            else if (cnt_max == arr[i]) {
                if (check)
                    continue;
                check = true;
                ans = i - 4000;
            }
        }
     
        cout << (int)round((double)(sum)/n) << '\n';
        cout << v[n/2<< '\n';
        cout << ans << '\n';
        cout << v[n - 1- v[0<< '\n';
        
     
     
        
        
        return 0;
    }
     
    cs
Designed by Tistory.