본문 바로가기

개발/백준

[백준] 2108번. 통계학 (C++)

문제 설명

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

 

해결 방법

까다로운 Mode(최빈값)만 살펴보자

 

numbers_mode는 각 숫자 별로 나온 값을 저장해 두기 위해 만들었다.

예를들어

-1이 3번 나온다면 numbers_mode[-1+MAX]=3

0이 5번 나온다면 numbers_mode[0+MAX[=5

일 것이다.

 

NoDuplicate는 numbers_mode를 통해 1번 이상 나온 숫자들을 저장한 벡터로

한번이라도 나온 숫자가 저장된다(중복 없이)

 

 

이제 모든 숫자들(즉 NoDuplicate에서)을 살펴보자

숫자가 max와 같다면 ModeCandidate에 넣는다(최빈값이 여러개일 수 있기 때문에)

숫자가 max보다 크다면 ModeCandidate도 초기화하고 max값도 갱신한다.(최빈값이 되기 위한 값이 더 높아짐)

이를 반복 후에 ModeCandidate를 정렬 후

최빈값이 1개 뿐이면 해당 값을 Mode로 설정하고

2개 이상이면 1번째 값을 선택한다.

 

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define MAX 500000

int main() {
	
	//INPUT/////////////////////////////////////////////////////////////////
	int Mean, Median, Mode, Range;

	int N;
	cin >> N;
	vector<int>numbers(N);
	vector<int>numbers_mode(MAX * 2 + 1,0);
	int num;
	long long sum = 0;
	for (int i = 0; i < N; i++)
	{
		cin >> num;
		sum += num;
		numbers[i] = num;
		numbers_mode[num + MAX] ++;
	}
	sort(numbers.begin(), numbers.end());

	//MEAN//////////////////////////////////////////////////////////////////
	Mean = round(sum / double(N));
	
	//RANGE/////////////////////////////////////////////////////////////////
	Range = numbers[N - 1] - numbers[0];

	//MEDIAN////////////////////////////////////////////////////////////////
	Median = numbers[(N - 1) / 2];



	//MODE/////////////////////////////////////////////////////////////////
	//중복 없이 입력받은 숫자들 저장
	vector<int>NoDuplicate;
	for (int i = 0; i < numbers_mode.size(); i++)
	{
		if (numbers_mode[i] != 0) { NoDuplicate.push_back(i-MAX); }
	}

	int max = 0;
	int index;
	vector<int>ModeCandidate;
	for (int i = 0; i < NoDuplicate.size(); i++)
	{
		index = NoDuplicate[i] + MAX;
		if (max == numbers_mode[index])
		{
			ModeCandidate.push_back(NoDuplicate[i]);
		}
		else if (max < numbers_mode[index])
		{
			max = numbers_mode[index];
			ModeCandidate.clear();
			ModeCandidate.push_back(NoDuplicate[i]);
		}
	}
	sort(ModeCandidate.begin(), ModeCandidate.end());
	
	//같은 개수 있으면 두번째로 작은값 선택
	if (ModeCandidate.size() == 1) { Mode = ModeCandidate[0]; }
	else { Mode = ModeCandidate[1]; }

	

	//RESULT PRINT///////////////////////////////////////////////////////////
	cout << Mean << "\n" << Median << "\n" << Mode << "\n" << Range;
}