본문 바로가기
백준BOJ/정렬, 투 포인터

백준 2108 통계학

by 이일아 2022. 6. 4.
반응형

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

 

2108번: 통계학

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

www.acmicpc.net

 

EXPLANATION

 

문제에서

 

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

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

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

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

 

라고 하였다.

 

산술 평균은 전체 누적합을 입력값의 개수로 나누면 되고

중앙값과 최댓값과 최솟값의 차이인 범위는 입력값을 받은 배열을 오름차순으로 정렬해서

중간에 있는 수를 구하고

가장 끝에 있는 수와 가장 처음에 있는 수의 차이를 구하면 된다.

 

최빈값은 입력값을 받을 때 입력값에 대한 정보를 index로 가지고 그 수의 빈도를 원소로 가지는 배열을 통해서 구할 수 있다. 예를 들어서, 2가 3번 나왔으면 frequency[2] = 3

 

 

 

 

CODE

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

vector<int> arr;
int main() {
    int N, num;
    int modeFrequency = -1;
    int frequency[8001] = {};
    bool isSecond = false;
    int sum = 0;
    
    cin >> N;
    for(int i = 0; i < N; i++) {
        cin >> num;
        arr.push_back(num);
        sum += num;
        frequency[num+4000]++;  //입력받는 수의 빈도를 저장하는 배열, 입력받는 수의 범위가 [-4000,4000]이고 인덱스는 0부터이므로 num을 index로 설정할 때 4000을 더해서 index와 범위안에 수들이 일대일 대응을 이루도록 한다.
    }
    
    int mean = round((float)sum / N); //산술 평균, 입력받은 수의 전체 누적합을 입력 받은 수의 갯수로 나눔
    
    
    sort(arr.begin(),arr.end());     //배열 오름차순으로 정렬
    int middle = arr[arr.size()/2];  //중앙값, 오름차순으로 정렬하고 가장 중간에 있는 값
    
    
    int mode = -1;  //최빈값 구하기
    for(int i = 0; i < 8001; i++) {
        if(frequency[i] == 0)  //i가 입력값으로 한번도 안나왔으면 그냥 넘김
            continue;
        
        if(frequency[i] > modeFrequency) {  //i의 빈도수가 지금까지 모든 수의 빈도보다 많으면 최빈값으로 재설정
            modeFrequency = frequency[i];
            mode = i - 4000;
            isSecond = true;
        }else {
            if(frequency[i] == modeFrequency) { //i의 빈도수가 변경된 최빈값의 빈도랑 같은 수이고
                if(isSecond) {                //그 i가 두번째 최빈값일 때 최빈값(mode) 변경
                    mode = i - 4000;
                    isSecond = false;        
                }
            }
        }
    }
    
    int range = arr.back() - arr.front(); //범위, 입력된 숫자들이 오름차순으로 배열됬을 때 가장 뒤에 수와 처음 수의 차이
    
    cout << mean << '\n' << middle << '\n' << mode << '\n' << range;
}

 

반응형

댓글