2108 통계학
2108. 통계학 / c++ / Silver3 / 20분
문제
https://www.acmicpc.net/problem/2108
- N개의 정수가 주어진다. (1 <= N <= 500’000, 각 정수의 절대값은 4’000을 넘지 않는다)
- 아래의 값들을 출력하시오.
- 산술평균 (소숫점 첫째 자리에서 반올림)
- 중앙값 (오름차순일 때 중앙에 위치한 값)
- 최빈값 (만약 최빈값이 여러개면 두번째로 작은 수)
- 범위
접근 방식
수학
- 산술평균은 범위가 -20억에서 +20억이고, 이를 실수로 처리해야 하므로 자료형을 double로 처리했다.
- 중앙값은 벡터에 다 담은 후 오름차순으로 sort하여 중앙 위치를 출력
- 최빈값은 map을 이용해서 값의 등장 빈도수를 저장한 후, vector로 옮겨서
- 빈도수가 큰 수
- 빈도수가 같다면 값이 작은 수 로 정렬한 후 처리해줬다.
- 범위는 입력받으면서 최대값 최소값을 찾아냈고, 그 두수의 차이를 출력
문제 풀이
#pragma GCC optimize("Ofast")
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
inline int MAX(int A, int B) { return A > B ? A : B; }
inline int MIN(int A, int B) { return A < B ? A : B; }
int N, num, maxNum, minNum;
double sum = 0;
vector<int> v;
map<int, int> m;
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> N;
for (int i = 0; i < N; ++i)
{
cin >> num;
sum += num;
v.push_back(num);
m[num]++;
if (i == 0)
{
maxNum = minNum = num;
}
else
{
maxNum = MAX(maxNum, num);
minNum = MIN(minNum, num);
}
}
// 산술 평균
int result = sum / N;
sum = sum / N;
float temp = sum - result;
if (sum - result >= 0.5) result++;
else if (sum - result <= -0.5) result--;
cout << result << '\n';
// 중앙값
sort(v.begin(), v.end());
cout << v[N / 2] << '\n';
// 최빈값
vector<pair<int, int>> v2(m.begin(), m.end());
sort(v2.begin(), v2.end(), [](pair<int, int> A, pair<int, int> B)->bool
{
if (A.second == B.second) return A.first < B.first;
return A.second > B.second;
});
if (v2.size() > 2 && v2[0].second == v2[1].second) cout << v2[1].first << '\n';
else cout << v2[0].first << '\n';
// 범위
cout << maxNum - minNum << '\n';
return 0;
}
다시 생각해 볼 점
- 산술값을 반올림 해줘야 했던 것, 반올림 시 음수는 -를 해줘야 했다는 것
- 중앙값은 오름차순 정렬 후 계산해줘야 했다는 것
- 최빈값은 동률일 경우 두번째로 작은 수를 출력해줘야 했다는 것
- 위의 것들을 제대로 처음에 발견하지 못해서 중간중간 수정해줬다.
- 처음부터 문제를 제대로 읽고 파악한 후 풀자.