문제
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는
다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다.
입력되는 정수의 절댓값은 4,000을 넘지 않는다.
출력
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.
예제 입력 1
5
1
3
8
-2
2
예제 출력 1
2
2
1
10
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 8e3 + 1;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
double avg = 0;
int median, mode, range;
vector<int> v;
// 1 ~ 4000 : 음수
// 4001 ~ 8000 : 양수
int arr[N] = {0,};
for(int i=0; i<n; i++) {
int num;
cin >> num;
v.push_back(num);
arr[num+4000]++;
avg += num;
}
sort(v.begin(), v.end());
int most = -500001;
bool is_second;
for(int i=0; i<N; i++) {
if(arr[i] == 0) continue;
if(arr[i] == most) {
if(!is_second) {
mode = i - 4000;
is_second = true;
}
}
if(arr[i] > most) {
most = arr[i];
mode = i - 4000;
is_second = false;
}
}
avg = round(avg / n);
median = v[n/2];
range = v.back() - v.front();
cout << avg << '\n' << median << '\n' << mode << '\n' << range;
return 0;
}
이 문제의 핵심은 음수처리와 최빈값이 핵심인것 같다.
배열의 인덱스는 음수값을 가질 수 없기 때문에, 0~4000까지는 음수, 4000~8000까지는 양수로 잡아야 한다.
문제에서 절댓값이 4000을 넘길 수 없으므로 -4000 ~ 4000까지의 범위를 가진다는 말이기 때문이다.
따라서 -4000은 0부터 시작하고, 0은 4000부터 시작하게 된다.
입력받은 값은 v벡터에 push해주고, 입력값이 몇번이나 나왔는지 arr배열에 카운트해준다.
그리고 입력받은 값들을 다 더해준다. 이 더해준 값은 나중에 평균을 구할 때 쓰인다.
최빈값을 구하는 방법은 arr배열이 수가 몇번이나 나왔는지 카운트 한 배열이기 때문에 그것을 이용하면 된다.
일단 입력 받는 수의 최대 개수가 50만개이때문에 일단 most변수를 -500001로 잡아준다.
그 후 반복문을 돌면서 체크해주면 되는데,
1. 만약 arr[i]값이 0일경우, 입력받지 않은 값이므로 continue 해주면 된다.
2. 만약 arr[i]가 most와 같을 경우, 문제에서 주어진대로 두번째로 작은 값을 구하면 되기 때문에 이것이 두번째 값인지
아닌지 bool형 변수를 통해 체크한뒤, 맞다면 true로 바꿔주고, 최빈값은 i-4000을 해주면된다.
3. 만약 arr[i]가 most보다 클 경우, most를 arr[i]로 바꿔주고 is_second를 false로 바꿔주면 된다.
이렇게 평균값은 아까 입력받은 값을 모두 더했기때문에, 그 값에서 n을 나눠준뒤 반올림 해주면된다.
중앙값은 위에서 sort를 해주었으므로 n/2의 인덱스의 값을 구해주면 된다.
범위는 sort를 해주었으므로 벡터의 맨마지막값에서 맨첫번째값을 빼주면된다.
'PS > 백준' 카테고리의 다른 글
백준 / 정렬 / 10814번 / 나이순 정렬 / C++ (0) | 2022.01.24 |
---|---|
백준 / 정렬 / 11651번 / 좌표 정렬하기 2 / C++ (0) | 2022.01.22 |
백준 / 정렬 / 10989번 / 수 정렬하기 3 / C++ (0) | 2022.01.20 |
백준 / 정렬 / 2750번 / 수 정렬하기 / C++ (0) | 2022.01.20 |