Notice
Recent Posts
Recent Comments
Link
궤도
[백준] 2108번 : 통계학 본문
문제
풀이
요구하는 것이 많지만, 이 중에서 까다로운건 최빈값 구하기 뿐이다. 입력을 받으면서 모든 배열의 합도 구해놓고, 최댓값과 최솟값도 구해놓는다. 그리고 해당 숫자의 등장 횟수도 count 배열을 갱신하며 기록해준다. 중요한건 입력으로 음수가 들어오기도 한다는 것이다. 범위가 -4,000~4,000 이니까 8,000 크기의 배열을 선언하고 입력으로 들어온 값에 4,000을 더한 인덱스를 갱신하면 된다. -4,000~4,000의 범위가 0~8,000으로 변하는 셈이다.
입력을 다 받았으면 중앙값을 구하기 위해 정렬한다. 그리고 count 배열을 돌며 최빈값을 체크한다. 해당 최빈값이 유일하다면 바로 출력하면 되지만, 유일하지 않다면 배열을 다시 돌며 최빈값 중 두 번째로 작은 값을 출력한다. 최빈값 중 제일 작은 값이 무엇인지 알고 있으니 그 다음 인덱스부터 돌면 된다.
소수점을 고정하기 위해 cout.precision(n)을 사용해왔다. 근데 이게 반올림을 해준다고도 한다. 그럼 그냥 지금까지 구한 값들을 편하게 출력하면 된다.
소스코드
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N, count[8001] = { 0, }, max = -4001, min = 4001, i;
double sum = 0.0;
bool isOne;
cin >> N;
int* arr = new int[N];
for (i = 0; i < N; i++) {
cin >> arr[i];
sum += arr[i]; //평균용 합 구하기
if (arr[i] > max) //최댓값 갱신
max = arr[i];
if (arr[i] < min) //최솟값 갱신
min = arr[i];
count[arr[i] + 4000]++; //음수도 저장하려고 4000 더한 값에 ++ 해줌
}
sort(arr, arr + N); //중앙값용 정렬
int mode_num, mode_count = 0; //최빈값용 변수
for (i = 0; i < 8001; i++) {
if (count[i] == mode_count) //유일한 최빈값인지 체크
isOne = false;
else if (count[i] > mode_count) {
mode_count = count[i];
mode_num = i - 4000; //원래 4000 더해서 받았으니까 4000 뺌. 만약 유일한 최빈값이면 얠 바로 출력
isOne = true;
}
}
if (!isOne) { //최빈값이 유일하지 않다면
for (i = mode_num + 4001; i < 8001; i++) { //받아놓은 mode_num이 첫번째 최빈값일테니까 그 다음부터 체크하면 됨
if (count[i] == mode_count) {
mode_num = i - 4000;
break;
}
}
}
cout << fixed;
cout.precision(0); //이게 반올림도 해준다고 함
cout << sum / N << '\n' << arr[N / 2] << '\n' << mode_num << '\n' << max - min << '\n';
}
Comments