본문 바로가기
Algorithm/Sort

2108번 통계학 BOJ 백준 C언어

by HenryNoh 2020. 7. 12.

문제

수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

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

N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.

입력

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

출력

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

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

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

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

구현

 

1. 산술평균은 간단하게 round 함수를 사용하여 입력받을 때마다 더한 값을 나누어서 사용할 수 있다.

2. 중앙값은 정렬해놓은 배열의 (num-1)/2 하여 구할 수 있다.

4. 범위는 최대값-최소값으로 구할수 있다.

3. 통계학 문제의 가장 중요점은 최빈값을 출력하는 것에 있다.

단순하게 최빈값을 출력하는 것은 입력 받은 값을 배열의 index로 취급하여 해당 배열의 값을 늘려주어서 최대 값을 출력하면 된다. 하지만 해당 문제에서는 여러 개가 있을 경우 두 번째로 작은 값을 출력해야 한다는 전제 조건이 있다. 따라서 모든 값을 입력 받은 후 전체 배열을 순회하며 값이 같을 경우 새로운 배열에 추가하고 더 높은 수가 나올 경우 값을 저장하는 배열을 초기화하여 새로 저장하는 방식으로 문제를 해결할 수 있다.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
#define Limit 8001

int main(void) {
int i, j=0, k = 0, n, num, mid, mode=0, size; //mid: 중간값 size: 범위
int sum = 0, max_num = 0; // max_num: mode값의 최대값 구하는 변수

scanf("%d", &num);
int *arr = (int*)malloc(sizeof(int)*num);
int count[Limit] = { 0 };
int max[Limit] = { 0 };

for (i = 0; i<num; i++) {
    scanf("%d", &n);
    sum = sum + n;
    max[n + 4000]++; //최빈값 구하기 위하여 각 입력받은 수의 해당칸에 ++ 시켜주기 (카운팅정렬)
}
double avg = round(sum / (double)num); // 반올림을 위해서 num을 double로 형변환

for (i = 0; i<Limit; i++) {
    if (max[i]>max_num) { //max 배열의 값이 max_num보다 클 경우 
        j = 0; //count 배열을 초기화 후
        max_num = max[i]; // max_num은 새로운 값으로 변경
        count[j] = i - 4000; //count[0]은 인덱스-4000의 값으로 저장
        j++;
    }
    else if (max[i] == max_num) { //max 배열의 값이 max_num과 같을 경우
        count[j] = i - 4000; //count[j]에 인덱스-4000의 값으로 저장
        j++;
    }
    if (max[i]>0) { //max 배열이 안 비어있는 경우
        while (max[i]>0) { 
            arr[k++] = i - 4000; //arr에 입력값 저장 (낮은 수부터 차례대로 저장되므로 mid에 사용)
            max[i]--; // max 배열을 비움
        }
    }
}
if (j == 1) { //j==1인 경우는 최빈값이 1개인 경우
    mode = count[0];
}
else if (j>1) { //j==1인 경우는 최빈값이 2개이상인 경우
    mode = count[1];
}
mid = arr[(num - 1) / 2];
size = arr[num - 1] - arr[0];

printf("%.f\\n", avg);
printf("%d\\n", mid);
printf("%d\\n", mode);
printf("%d", size);
free(arr);
}

'Algorithm > Sort' 카테고리의 다른 글

가장 큰 수  (0) 2021.04.28
K번째수 Programmers 프로그래머스 C++  (0) 2020.08.26
11650번 좌표정렬 BOJ 백준 C언어  (2) 2020.07.12
2750번 정렬(O(n^2)) BOJ 백준 C언어  (0) 2020.07.11

댓글