<알고리즘 문제풀이&연습>/[C++] 백준, 프로그래머스 등등

[백준 2108] 통계학 (최빈값, 산술평균, 중앙값, 범위)

BlockDMask 2017. 8. 11. 16:52
반응형
  • 안녕하세요. BlockDMask 입니다. 

  • 오늘의 문제는
    STL에 vector 를 이용해서 풀었습니다.
    vector에 pair 클래스도 넣고 풀어봤으니, 
    vector<pair<int, int> > 예제 느낌으로 봐주셔도 좋을 듯 합니다.
    또한, sort 알고리즘을 사용할때 조건자를 줘서 기준을 바꿔 sort 하는 것도 나옵니다.
    sort(st.begin(), st.end(), comp) 도 유심히 봐주시면 좋을 듯 합니다.

0. 제목

  • 백준 2108 통계학

  • BOJ 2108 통계학

1. 문제설명 


n이 홀수일때

산술평균, 중앙값, 최빈값, 범위 를 구하여 각각 한 줄씩 출력하라.


<산술평균>

n개의 숫자들의 합을 n으로 나눈값을 말한다.

(소숫점 이하 첫째자리에서 반올림한다.)


<중앙값>

n개의 숫자들을 증가하는 순서대로 정렬했을때, 중앙에 위치하는 값을 말한다.


<최빈값>

n개의 숫자들을 빈도수가 가장 많은 값을 말한다.

(최빈값이 여러개 있을때에는 두번째로 작은 값을 출력한다.)


<범위>

n개의 숫자들 중 최대값과 최소값의 차이를 말한다.


2. 풀이과정


산술평균은 key값을 처음 받을때 for문에서 다 더하여서 구했습니다.

반올림을 구할대는 floor(내림) 메소드를 이용하여 구하였습니다. 

-> 내림 올림 함수 설명  [바로가기]


중앙값은 조건자 없는 sort 알고리즘으로 정렬된 vector 값들중 중앙값 반환해서 구했습니다.


최빈값은 이미 vector로 정렬된 값을 vector<pair<int, int> > 를 통해서 

key값과 빈도수를 pair로 묶어서 집어넣었습니다. 


동일한 key값이 나온다면 value(빈도수)를 증가시켜서 집어 넣습니다. 

(정렬이 되어있으므로 동일한 key값이 바로 다음에 들어올 수 있습니다.)


vector<pair<int, int> > 에 다 집어넣은 후에는 comp 출력 기준에 맞추어 정렬을합니다.

(빈도수가 큰순서대로, 빈도수가 같으면 key값이 작은 순서대로)


맨앞에 값과 두번째 값이 같으면 (최빈값이 2개라는 뜻) 두번째 값 출력

그렇지 않으면 첫번째 값을 출력. 

하는 방법으로 구하였습니다.


범위는 정렬된 vector의 첫번째 값과 맨 마지막 값의 차를 구했습니다. 

v.back() - v.front()


3. 코드


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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<stack>
 
using namespace std;
 
//sort 기준 
bool comp(const pair<intint> &p1,const pair<intint> &p2){
    
    if(p1.second == p2.second){     //빈도수가 같으면 
        return p1.first < p2.first; //숫자(key)작은게 앞으로 
    }
    return p1.second > p2.second;    //다르면 빈도수가 큰게 앞으로 
    
}
 
int main(void){
    //입력 1
    int n;
    cin >> n;
    
    vector<int> v;
    int    key;     
    double sum=0;    //산술평균용 
    
    //입력 2    
    for(int i=0; i<n ;i++){
        cin >> key;        
        v.push_back(key);
        
        sum += key;
    }
    
    //오름차순으로 정렬. 
    sort(v.begin(), v.end());    
    
    //산술평균 출력. 
    //내림함수를 이용하여 반올림.
    cout <<  (int)floor( (sum / n) + 0.5<< endl;
    
    
    //중앙값. 
    cout << v[n/2<< endl;
    
    
    //최빈값. 
    vector<pair<int,int> > st;            //key 와 빈도수를 저장할 pair형 vector. 
    vector<int>::size_type i;
    
    for(i=0; i<v.size(); i++){
        if(st.empty()){
            st.push_back(pair<int,int>(v[i],1));
            continue;
        } 
 
        if(st.back().first == v[i]){        //같은게 있다면 
        
            pair<intint> tmp = st.back();    
            tmp.second++;                    //하나 증가 
            st.pop_back();                    //기존것 없애고 
            st.push_back(tmp);                //새로운 것 다시 삽입 
        
        }else
            st.push_back(pair<int,int>(v[i],1));    
        }
    }
    
 
    //빈도수가 높고, 숫자(key)가 낮은 순으로 정렬 
    sort(st.begin(), st.end(), comp); 
    
    if(st[0].second == st[1].second){
        cout << st[1].first << endl;
    }else{
        cout << st[0].first << endl;
    }
    
    
    //범위.
    cout << v.back() - v.front() << endl;
    
    
    return 0;    
}
cs


4. 인증


문제 출처

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

반응형