학습 정리/👨‍💻 PS Study

[C++] 백준 2108번 - 통계학

무딘붓 2023. 1. 22. 22:07

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

 

2108번: 통계학

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

www.acmicpc.net

[소스코드]

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
// [baekjoon] 2108번 - 통계학
// 2023.01.22

int arr[800001] = { -5000 };

int main(void) {

	cin.tie(NULL);
	ios::sync_with_stdio(false);

	int n;
	cin >> n;

	int sum = 0;

	int cntNumArr[8001] = { 0 };
	int maxCntNum = 0;			// (가장 작은) 최빈값
	int maxCntNum2nd = -1;		// 최빈값 중 두 번째로 작은 값

	for (int i = 0; i < n; i++) {
		cin >> arr[i];
		sum = sum + arr[i];
		cntNumArr[arr[i] + 4000]++;
	}

	// 최빈값 구하기
	for (int i = 1; i < 8001; i++) {
		if (cntNumArr[i] > cntNumArr[maxCntNum]) {
			maxCntNum = i;
			maxCntNum2nd = -1;
		}
		else if (cntNumArr[i] == cntNumArr[maxCntNum] && maxCntNum2nd == -1) {
			maxCntNum2nd = i;
		}
	}
	
	sort(arr, arr + n);

	cout << (int)round(double(sum) / n) << "\n";
	cout << arr[n / 2] << "\n";
	if (maxCntNum2nd == -1) {
		cout << maxCntNum - 4000 << "\n";
	}
	else {
		cout << maxCntNum2nd - 4000 << "\n";
	}
	cout << arr[n - 1] - arr[0] << "\n";


	return 0;
}

 

이 문제를 풀기 위해선 산술평균과 최빈값을 구하는 것이 관건입니다.

 

산술평균의 경우 소수점 이하 첫째 자리에서 반올림한 값을 구해야 하는데, 이부분에서 실수하기 쉽습니다.

 

 

최빈값을 구하는 것은 문제 속에 힌트가 있습니다.

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

 

즉, 입력되는 정수의 범위는 -4000~4000 총 8001개이므로

그만큼의 배열을 만들어서 정수를 입력 받을 때 해당 배열의 개수를 저장해주면 됩니다.

 

최빈값이 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력해야 하는 점이 까다롭기는 하지만,

조건문으로 적당히 구현하면 어렵지 않게 풀어낼 수 있습니다.


중앙값과 범위는 정렬만 해주면 구할 수 있는 값이라 구하기 쉽습니다.

 

c++에서 sort()를 이용한 정렬에 대해서는 아래 게시글을 참고해주세요

https://sirius7.tistory.com/85