[2108] 통계학
📝 문제
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
💡 생각
문제에서 구해야 하는 값이 총 4가지인데, 그 중 중앙값과 범위는 정렬한 후에 추출해내야 하는 값이고 산술평균과 최빈값은 정렬하지 않고 얻을 수 있는 값이다.
따라서 N개의 수를 입력 받을 for문 안에서 산술평균과 최빈값을 얻기 위해 필요한 과정을 수행하였다.
- 최빈값 구하기
문제에서 입력되는 정수의 절댓값이 4000을 넘지 않는다고 하였으므로 -4000~4000 사이의 정수를 입력받을 수 있을 것이다.
최빈값을 구하기 위해 원소의 개수가 8001개의 배열을 생성하고 0으로 초기화 해준다.
숫자가 들어올 때 마다 해당 숫자를 배열 번호를 가진 배열값을 1 더해준다. (음수일 경우 절대값에 +4000을 하여 4001~8000 인덱스에 저장)
그 값이 전의 max값과 같다면 최빈값 배열에 push하고, max값보다 크다면 최빈값 배열을 비우고 해당 값을 push한다.
해당값이 최빈값이라는 뜻이므로, max값도 업데이트 해준다.
💻 코드
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int N;
double num; // 입력받는 정수
vector<double> v; // 정수들을 받을 배열
vector<int> vol(8001, 0); // 숫자들의 개수를 구할 배열(최빈값 구하기 위함)
vector<double> mode_v; // 최빈값 후보 배열
cin >> N;
int max = 1;
int n;
int hap = 0; // 입력받는 정수들의 합
for (int i = 0; i < N; i++) {
cin >> num;
v.push_back(num);
hap += num;
n = abs(num);
if (num < 0) n += 4000; // 음수면 배열 인덱스값을 양수로 만들기 위해
vol[n]++;
if (vol[n] == max) mode_v.push_back(num); // 최빈값 후보 배열에 push
else if (vol[n] > max) { // max보다 크다면 새로운 최빈값
mode_v.clear(); // 이전 후보들 최빈값 아니므로 clear
mode_v.push_back(num); // 새로운 최빈값 push
max = vol[n];
}
}
sort(v.begin(), v.end());
sort(mode_v.begin(), mode_v.end());
// 1. 산술평균
double temp = hap / double(N);
cout << round(temp) << endl;
// 2. 중앙값
cout << v[v.size() / 2] << endl;
// 3. 최빈값
if(mode_v.size() > 1)
cout << mode_v[1] << endl;
else
cout << mode_v[0] << endl;
//4. 범위
cout << v[v.size()-1] - v[0] << endl;
}
산술평균에서 삽질했는데 double 형변환 해주는 부분을 제대로 안해서...
테스트 케이스에 -9 / 5 를 해서 산술평균이 -2가 나오는 문제를 보고 음수의 경우를 나눠서 했었는데 이게 틀린거였다!
어떤분이 21% 돌아가다가 실패뜨면 산술평균에서 잘못된거라고 블로그에 써주셔서 망정이지 아니었으면 엉뚱한 부분만 계속 팠을 것 같다 ㅜ.ㅜ
Author And Source
이 문제에 관하여([2108] 통계학), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hyeonsik/백준-2108-통계학저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)