Algorithm/백준

[백준] 2108 통계학 with C++

nowkoes 2023. 5. 4. 00:00

문제설명


입출력 예제


개념

 다양한 수를 처리하는 문제다. 산술 평균, 중앙값, 범위는 간단하게 해결할 수 있지만, 최빈값을 처리하는 과정이 까다롭고, 시간 초과에 자주 걸리므로 알고리즘 최적화를 잘해야 한다.


풀이

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <unordered_map>
using namespace std;

int main()
{
	int N, sum = 0;
	cin >> N;
	vector<int> v(N);
	unordered_map<int, int> freq;

 수의 개수 N, 산술 평균을 계산하기 위한 sum, 중앙값과 범위를 계산하기 위한 벡터 v, 최빈값을 계산하기 위한 해시맵 freq를 초기화한다.

 

	for (int i = 0; i < N; i++)
	{
		cin >> v[i];
		sum += v[i];
		freq[v[i]]++;
	}

	int mean = round((double)sum / size);

 산술 평균을 구하는 과정이다. 벡터 내의 모든 원소를 더해서 벡터의 크기만큼 나눠주면 된다. 이때 소수 첫 번째에서 올림을 해야하고, 정수에서 실수로 계산되는 부분이 있으므로 형변환을 반드시 해줘야 한다. 

 그리고 최빈값 계산을 위해 freq에 v[i]의 개수를 삽입하자.

 

    sort(v.begin(), v.end());
    int size = v.size();
    int center = v[size / 2];

 중앙값 계산을 위해 벡터를 정렬하고 인덱싱을 통해 중앙에 있는 값을 center에 초기화한다.

 

	vector<pair<int, int>> tmp(freq.begin(), freq.end());
	sort(tmp.begin(), tmp.end(), [](auto const& l, auto const& r)
		{
			return l.second != r.second ? l.second > r.second : l.first < r.first;
		});

	int fre = tmp[0].first;

	if (tmp.size() > 1 && tmp[0].second == tmp[1].second)
		fre = tmp[1].first;

 가장 자주 나오는 수를 벡터 tmp에 정렬한다. 이때 람다식을 이용해서 가장 많이 나온 수를 앞쪽으로 정렬한다. 그리고 만약 최빈값의 개수가 같은 수가 2개 이상 있으면 2번째 값을 갖게 해 준다.  

 

	int range = v[size - 1] - v[0];
	
	std::cout << mean << '\n' << center << '\n' << fre << '\n' << range << '\n';
}

 이미 정렬된 벡터의 끝 값과 처음 값을 빼서 범위를 구한 후, 구한 값들을 출력하면 된다.

 

총합본

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <unordered_map>
using namespace std;

int main()
{
	int N, sum = 0;
	cin >> N;
	vector<int> v(N);
	unordered_map<int, int> freq;

	for (int i = 0; i < N; i++)
	{
		cin >> v[i];
		sum += v[i];
		freq[v[i]]++;
	}

	sort(v.begin(), v.end());

	int size = v.size();

	int mean = round((double)sum / size);

	int center = v[size / 2];

	vector<pair<int, int>> tmp(freq.begin(), freq.end());
	sort(tmp.begin(), tmp.end(), [](auto const& l, auto const& r)
		{
			return l.second != r.second ? l.second > r.second : l.first < r.first;
		});

	int fre = tmp[0].first;

	if (tmp.size() > 1 && tmp[0].second == tmp[1].second)
		fre = tmp[1].first;

	int range = v[size - 1] - v[0];
	
	std::cout << mean << '\n' << center << '\n' << fre << '\n' << range << '\n';
}
반응형