관리 메뉴

한다 공부

[C++] 백준 알고리즘 2108 통계학 본문

Algorithm/문제풀이

[C++] 백준 알고리즘 2108 통계학

사과당근 2021. 9. 27. 05:20

2108번: 통계학 (acmicpc.net)

 

2108번: 통계학

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

www.acmicpc.net

1. 산술평균의 경우 반올림값을 유의한다

2. 중간값의 경우, 입력 갯수가 홀수이므로 어렵지 않다

3. 최빈값의 경우, pair에 넣어서 빈도수를 비교하고 재정렬한다

4. 범위의 경우 차의 절댓값을 이용한다

 

최빈값이 까다롭지만 pair를 이용한다면 비교하기 수월하다.

이 문제는 함수를 많이 만드는 바람에 return을 자꾸 깜빡해서 런타임 에러가 많이 났었다 ㅠ

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

using namespace std;

int ave(vector<int> v) {
	double sum = 0;
	for (int i = 0; i < v.size(); i++) {
		sum += v[i];
	}
	//평균값이 -1.7의 경우 -2를 나타내고 싶고
	//1.7의 경우 2를 나타내고 싶음
	if (sum>0)
		return (int)double(sum / v.size() + 0.5);
	else
		return (int)double(sum / v.size() - 0.5);
}

int mid(vector<int> v) {
	int m = v.size() / 2;
	return v[m];
}

//pair를 이용해서 최빈값 저장
bool my_sort(const pair<int,int> &a, const pair<int, int> &b) {
	//빈도수가 같으면 숫자 작은 순으로
	if (a.second == b.second)
		return a.first < b.first;
	//빈도수가 다르면 빈도수 큰 순으로
	else
		return a.second > b.second;
}

int mode(vector<int> v) {
	//입력값이 하나일 경우 자기자신 리턴
	if (v.size() == 1)
		return v[0];

	vector<pair<int, int>> p;
	for (int i = 0; i < v.size(); i++) {
		//페어에 첫 값 넣기
		if (p.empty())
			p.push_back(make_pair(v[i], 1));
		
		//중복된 숫자면 빈도수 second만 ++
		else if (v[i] == p.back().first)
			p.back().second++;

		//중복되지 않으면 make_pair
		else
			p.push_back(make_pair(v[i], 1));
	}

	//빈도수 순으로 정렬
	sort(p.begin(), p.end(), my_sort);

	//빈도수 같은게 있으면 두번째 작은 수 리턴
	if (p[0].second == p[1].second)
		return p[1].first;
	else return p[0].first;
}

int range(vector<int> v) {
	int r;
	//벡터 요소가 하나면 범위는 0
	if (v.size() == 1) {
		return 0;
	}
	r = (v[0] - v[v.size() - 1]);
	//범위는 양수로 출력
	return abs(r);
}

int main() {
	int n, temp, k;
	vector<int> v;

	cin >> n;
	temp = n;
	while (temp--) {
		cin >> k;
		v.push_back(k);
	}

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

	cout << fixed;
	cout.precision(1);

	cout << ave(v) << '\n';
	cout << mid(v) << '\n';
	cout << mode(v) << '\n';
	cout << range(v) << '\n';

}