🖥️ CS/Baekjoon Algorithms

#2108번 통계학 (c++)

한국의 메타몽 2020. 3. 8. 02:59
#include <iostream>
#include <cmath>
using namespace std;

void Questions(int T){
    int arr[8001] = {0,}; //-4000과 4000도 포함
    double sum = 0; // 전체 합
    int middle = 0, mid_ans = (T/2)+(T%2); // 중앙값 1,2
    int mid_ans_check = false;
    int often_used = 0, often_used_ans = 0; // 최빈값 1,2
    bool often_used_check = false; // 최빈값이 여러개일 경우를 대비한 조건
    int max = 0, min = 8000; // 최대값, 최소값
    
    for(int i=0; i<T; i++){
        int a = 0;
        cin >> a;
        arr[4000+a]++;
        sum += a;
    }
    for(int i=0; i<8001; i++){ //최대 최소값 구하기, 중앙값 구하기 최빈값 구하기 1,
        if(arr[i]!=0){
            if(mid_ans_check==false){
                for(int j=0; j<arr[i]; j++){
                    middle++;
                    if(mid_ans_check==false&&middle==mid_ans){
                        mid_ans = i;
                        mid_ans_check=true;
                    }}}
            if(often_used<=arr[i])
                often_used = arr[i];
            if(min>i)
                min = i;
            if(max<i)
                max = i;
        }
    }
    for(int i=0; i<8001; i++){ // 최빈값 구하기 2
        if(arr[i]==often_used){
            if(often_used_check==true){
                often_used_ans = i;
                break;
            }
            else if(often_used_check==false){
                often_used_ans = i;
                often_used_check = true;
            }
        }
    }
    if(round(sum/T)==-0) cout << 0 << "\n";
    else cout << round(sum/T) << "\n";
    cout << mid_ans-4000 << "\n";
    cout << often_used_ans-4000 << "\n";
    cout << (max-4000) - (min-4000) << "\n";
}

int main(void){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T;
    cin >> T;
    Questions(T);
    
    return 0;
}

문제를 읽어보면 쉽지만, 막상 푸는데 애로사항이 하나 둘 보이는 문제.

당당히 문제를 풀고 틀렸다는 결과가 나왔다면 아래 사항들을 고려해보아야 한다. 

 

1. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

: 즉, -4000도 입력이 가능하다. 

2. 배열로 값을 저장할 경우, 최대값의 범위가 잘 맞는지 확인하자. 

: 내 경우엔 8001이라고 적혀있다. 

3. 산술평균을 구할때, 답이 '-0'이라고 나와서 틀리는 경우가 있다. 

https://www.acmicpc.net/board/view/44712 <-를 참고하자. 

4. 산술평균을 구할때, 합계를 float로 저장하면 틀린다. 

: double로 저장하자. 난 이 점을 간과했다가 1시간이나 시간을 낭비했다. 

왜 float은 안되고 double은 되는가? 나는 질문을 올렸다가 하단과 같은 답변을 듣게 되었다. 

문제에서는 input값의 갯수로 500,000개나 들어갈 수 있다고 말했다. 

분명 이 과정에서 '오차'는 분명 발생할거고, 입력값이 누적되어감에 따라 오차의 크기는 무시하지 못할 것이다. 

5. 중앙값을 구할때 실수가 자주난다.

: 내가 생각한 중앙값을 컴퓨터가 잘 계산한건지 한 번 쯤은 고민하자.

 

온갖 테스트케이스를 구해가며 이 한 문제를 집중해서 풀 덕에, 

내가 간과하고있던 중요한 포인트들을 많이 깨닫고 갔다.