공부용 이모저모
2108번 - 통계학 본문
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.
사실상 문제가 4개이다.
최빈값이 뭔소린지 이해하는데 좀 많이 걸렸다.
#include<stdio.h>
#include <algorithm>
#include <vector>
#pragma warning(disable:4996)
using namespace std;
int main(void) {
int t,q;
int cnt_num[8005] = { 0 },mode_cnt = 0, mode_num = 0;
vector<int> data;
vector<int> mode;
//vector<int> middle; //중간값
//vector<int> t;
scanf("%d", &t);
double sum = 0 ;
for (int i = 0; i < t; i++)
{
scanf("%d", &q);
//middle.push_back(q);
sum += q;
data.push_back(q);
//최빈값
int idx = q < 0 ? 8001 + q : q;
cnt_num[idx]++;
if (mode_cnt < cnt_num[idx]) {
//빈도가 더 높은 값이 나온다면
mode_cnt = cnt_num[idx];
mode.clear();
mode.push_back(q);
}
else if (mode_cnt == cnt_num[idx]) {
mode.push_back(q);
}
}
//1번
printf("%0.f\n", sum / t);
sort(data.begin(),data.end());
printf("%d\n", data[t / 2]);
//최빈값
if (mode.size() > 1)
{
sort(mode.begin(), mode.end());
printf("%d\n", mode[1]);
}
else
printf("%d\n", mode[0]);
//4번
printf("%d", data[t - 1] - data[0]);
return 0;
}
1,2,4번은 사실상 일맥상통한다.1번의 경우는 조건 때문에 %0.f를 사용했다.
현재까지의 값을 다 더한뒤 개수만큼 나누면 된다.
sort로 오름차순 정렬을 하면 2번과 4번문제는 해결된다.
2번은 중간값, 4번은 자연스럽게 마지막 값이 제일 크고 맨 앞이 제일 작다.
3번이 좀 난해했다. 최빈값이라는게 가장 많이 쓰인 수를 얻어내는건데,
여기서 가장 많이 쓰인 수가 여러개라면, 정렬 후 두 번째로 작은 값을 출력해야 하므로
최빈값들을 리스트업 시킬 필요가 있다.최빈값이 새로 생성되었을땐 기존의 벡터를 초기화 시켜야 한다.
여기선 배열을 사용했지만 map으로 관리하는것도 괜찮지 않을까 생각한다.
물론 sort하기 위해 한번 옮겨야 해서 좀 느려질것 같다.
'백준' 카테고리의 다른 글
2914번 - 저작권 (0) | 2021.07.21 |
---|---|
2442번 - 별찍기 5 (0) | 2021.07.15 |
10825번 - 국영수 (0) | 2021.07.06 |