https://www.acmicpc.net/problem/2108
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
입력받은 숫자들의 통계값을 출력하는 문제. 개인적으로 최빈값을 출력하는 과정이 제일 힘들었다. N이 홀수로 제한되어있기 때문에 중앙값은 구하기 쉽다. 평균의 경우 반올림에 주의하자.
최빈값의 경우, 등장횟수를 다 저장한 후에, max_element 함수를 이용해서 해결했다.
max_element의 경우, 주어진 범위 내에서 가장 큰 요소의 첫번째 위치를 반환한다. 예를 들어, {1, 2, 3(1), 2, 3(2), 1} (3 옆의 숫자는 구분을 위한 숫자) 이라는 배열에서 이 함수를 적용한 경우, 첫번째 3, 그러니까 3(1)의 위치를 반환한다. 이를 응용하여 문제를 해결했다.
#include <iostream>
#include <array>
#include <algorithm>
#include <functional>
#define MAX(A,B) A > B ? A : B
#define MIN(A,B) A < B ? A : B
using namespace std;
int main () {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
int min = 8001, max = -8001;
int maxElem;
double avg = 0;
array<int, 8001> numCount = {0}; // -4000 ~ 4000 -> 0 ~ 8000
array<int, 8001>::iterator maxIndex;
cin >> n;
int * arr = new int[n];
for (int i = 0; i < n; i++) {
cin >> arr[i]; // 입력받는다.
avg += arr[i]; // 평균을 위한 총합
max = MAX(max, arr[i]); // 최댓값 찾기
min = MIN(min, arr[i]); // 최솟값 찾기
numCount[arr[i] + 4000]++; // 등장횟수 저장
}
avg /= n; // 평균
avg > 0 ? avg += 0.5 : avg -= 0.5; // 반올림. 부호에 유의한다.
sort(arr, arr + n, greater<>()); // 중앙값 찾기
maxIndex = max_element(numCount.begin(), numCount.end()); // 최빈값 찾기. 첫번째 최빈값의 위치를 받는다.
// 첫번째 최빈값 그 다음위치에서 최빈값을 다시 찾는다.
if (*maxIndex != *max_element(maxIndex+1, numCount.end())) // 만약 등장횟수가 다르다면,
maxElem = (int)(maxIndex - numCount.begin()) - 4000; // 최빈값은 한개. 배열의 첫 주소로부터의 거리를 잰 후에 4000을 뺀다
else // 등장횟수가 같다면
maxElem = (int)(max_element(maxIndex + 1, numCount.end()) - numCount.begin()) - 4000; // 그 다음 최빈값의 위치로 동일한 과정.
cout << (int)avg << '\n'; // 정수값으로 출력
cout << arr[n / 2] << '\n'; // 중앙값
cout << maxElem << '\n'; //
cout << max - min << '\n'; // 최대 - 최소 = 범위
delete[] arr;
}
'coding_test > BAEKJOON' 카테고리의 다른 글
백준 18870번 C++ 풀이 (0) | 2021.11.29 |
---|---|
백준 1427번 C / C++ 풀이 (0) | 2021.11.29 |
백준 11651번 C / C++ 풀이 (0) | 2021.11.29 |
백준 10814번 C, C++ 풀이 (0) | 2021.11.25 |
백준 11650번 C, C++ 풀이 (0) | 2021.11.25 |