[백준/C++] 2018 - 통계학

정승우·2021년 2월 14일
0

[백준/C++] BOJ 공부

목록 보기
1/25

문제링크: https://www.acmicpc.net/problem/2108

문제


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

산술평균 : N개의 수들의 합을 N으로 나눈 값
중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
최빈값 : N개의 수들 중 가장 많이 나타나는 값
범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.

입력


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

출력


첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.

풀이


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

int main() {
	std::ios::sync_with_stdio(false);
	std::cout.tie(NULL);
	std::cin.tie(NULL);

	int N; std::cin >> N;
	std::vector<int> v(N);
	std::vector<int> vcount(8001, 0);

	int sum = 0;
	int modecount = 0;
	for (int i = 0; i < N; i++) {
		std::cin >> v[i];
		sum += v[i];
		vcount[v[i] + 4000]++;
		if (vcount[v[i] + 4000] > modecount) {
			modecount = vcount[v[i] + 4000];
		}
	}

	// arithmetic mean
	std::cout << round(sum / (double)N) << "\n";

	std::sort(v.begin(), v.end());
	
	// median
	if (N % 2 == 0) {
		std::cout << (v[N / 2 - 1] + v[N / 2]) / 2 << "\n";
	}
	else {
		std::cout << v[N / 2] << "\n";
	}

	bool second = false;
	int mode = 0;
	for (int i = -4000; i <= 4000; i++) {
		if (vcount[i + 4000] == modecount) {
			mode = i;
			if (second) {
				break;
			}
			second = true;
		}
	}
	// mode 
	std::cout << mode << "\n";

	// range: <<max - min>>
	std::cout << v[v.size() - 1] - v[0] << "\n";

	return 0;
}

산술평균 구하기
(전체의 합) / 개수

단, 산술평균을 구할 때의 개수(N)는 double형이여야 한다. 그래야만 반올림이 가능해진다.

중앙값 구하기
짝수일 때: (v[N/2 - 1] + v[N/2])/2
홀수일 때: v[N/2]

중앙값은 sort를 했을 때 중앙에 있는 값이다. 짝수일 때는 가운데 두 수의 평균을 중앙값으로 삼는다.

최빈값 구하기
범위 크기의 배열을 만들어 값을 넣을 때마다 수를 증가시켜, 가장 큰 값을 가지는 수

배열을 만들어 가장 많이 배열에 넣어진 값을 출력한다.
단, 값이 2개 이상이면 boolean형의 flag를 통해 첫 값은 pass하고 다음 두번 째 값을 받아온다.

범위 구하기
(마지막 값) - (처음 값)

산술평균과 같이 가장 쉬운 부분이다.
sort 후에 단순히 맨 마지막 값에서 처음 값만을 빼주면 된다.

노트


최빈값을 어떻게 쉽게 구하는지가 핵심이다.
간단하게 풀어 넘길 것 같은 문제였지만,
의외로 최빈값에서 2번째로 작은 값을 출력하는 것이 어려운 문제였다.

profile
Computer Science & Engineering 19

0개의 댓글