출처 : https://www.acmicpc.net/problem/2108
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
최반값이 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
개념 자체는 간단하지만, 예외 조건이 쪼끔 달려있는 문제이다. 반올림은 round 함수를 이용해서 처리하면 되고, 최빈값 중 두번째로 작은값을 출력하는 걸 잘 생각해야 하는 문제이다. 또, 평균에서-0.0
이라는 이상한 숫자가 나올 수도 있으니까, 이것 또한 예외처리 해야한다.
최빈값을 찾으려면, 다행히 문제에서는 정수의 절대값이 4000을 넘지 않으므로 모든 숫자에 대한 배열을 만들 수 있고 , counting을 해주면 최빈값을 알아내는건 어렵지 않다.
하지만, 두번째 작은값을 출력하라는 걸 생각해보자. 최빈값이 여러개 일 때, 우리가 구하는 최빈값은 제일 처음 만나는 최빈값일거다. 즉, 제일 처음 == 제일 작은 최빈 값이므로, 해당 값 이후에 또 최빈값이 나오면 그 수가 두번째 작은 값이다.
즉, for문을 한번돌아서 최빈값 구하기 -> 해당 숫자 기억 -> 해당 숫자부터 또 최빈값이 있다면, 변경해주기
#include <bits/stdc++.h>
#define fastio cin.tie(0)->sync_with_stdio(0)
using namespace std;
int N;
int mxVal = INT_MIN;
int mnVal = INT_MAX;
int arr[500001];
int num[8001];
int main()
{
fastio;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> arr[i];
}
sort(arr, arr + N);
int total = 0;
for (int i = 0; i < N; i++)
{
if (mxVal < arr[i])
mxVal = arr[i];
if (mnVal > arr[i])
mnVal = arr[i];
num[arr[i] + 4000]++;
total += arr[i];
}
// 최빈값이긴 한데, 같은게 있는지 없는지 확인해야함.
int mxCnt = INT_MIN;
int t = 0;
for (int i = 0; i < 8001; i++)
{
if (mxCnt < num[i]){
mxCnt = num[i];
t = i;
}
}
bool flag = false;
int freqVal = 0;
for (int i = t + 1; i < 8001; i++)
{
if (mxCnt == num[i])
{
freqVal = i - 4000;
break;
}
}
int avg = round((float)total / N);
if (avg == -0.0)
avg = +0.0;
cout << avg << '\n';
cout << arr[N / 2] << '\n';
cout << freqVal << '\n';
cout << mxVal - mnVal << '\n';
return 0;
}