-
백준 2108 (통계학) c++백준 문제 2022. 7. 19. 20:13728x90
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N이 주어지고 N개의 수를 입력하면 위의 4가지를 모두 구하는 것입니다.
N은 무조건 홀수로 주어집니다.
1) 산술평균은 먼저 모든 N개의 수의 합을 구해야 하므로 처음에 입력 받을 때 부터
sum 이라는 int형 변수에 누적으로 더해주었습니다.
문제에서 소수점 아래 첫째 자리에서 반올림을 해줘야 하므로 round함수를 이용했습니다.
소수점을 다뤄줘야 하므로 나눌 때 double형으로 캐스팅 해주고
이를 round함수의 인자로 넣어 주면서 다시 int형으로 캐스팅 해주었습니다.
cout << (int)round((double)(sum)/n) << '\n';
2) 중앙값은 먼저 N개의 수를 벡터에 넣어 오름차순으로 정렬한뒤
[N/2] 번째 인덱스 값을 출력해 주면 됩니다.
N은 무조건 홀수로 들어오기 때문입니다.
cout << v[n/2] << '\n';
3) 이 문제의 핵심 부분입니다.
최빈값은 말 그대로 가장 많이 등장한 숫자를 말합니다.
N의 범위가 50만 이기 때문에 2차원 반복문을 돌게 되면 시간초과가 일어납니다.
또한 최빈값이 여러개일 경우 2번째로 작은 값을 구해야 합니다.
수의 범위는 -4000 ~ 4000 입니다.
음수는 배열의 인덱스로 저장 할 수 없습니다.
어차피 범위가 4000까지 이므로 배열의 인덱스를 8000까지 잡으면 해결할 수 있습니다.
ex) 만약 -8으로 배열로 표현하고 싶으면 arr[-8 + 4000]을 이용해 음수를 표현할 수 있습니다.
먼저 처음에 N개의 수를 입력받을 때 작업해줍니다.
위와 같이 arr배열에 값이 들어왔다는 값을 세어주는 것입니다.
이제 최빈값을 세어주는 부분입니다.
0부터 8000까지 돌면서 가장 최빈값을 갱신해주는 것입니다.
이 떄 최빈값이 복수개이면 2번째로 작은 값을 구해줘야 하므로 boolean 형 변수를 둬서
맨 처음에 최빈값이 들어오게 되면 가장 작은 값이고
그 다음에 똑같은 최빈값이 들어오면 2번째로 작은 값이 므로 최빈값을 다시 갱신해주고 boolean 형 변수를 true로
바꾸어 이제 갱신할 수 없도록 만듭니다.
cout << ans << '\n';
4) 범위는 아까 벡터를 정렬해주었으므로 가장 작은 값은 v[0]일 것이고 가장 큰 값은 v[N-1]일 것입니다.
cout << v[n - 1] - v[0] << '\n';
전체 코드입니다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <string>#include <stack>#include <queue>#include <deque>#include <cmath>#include <map>#include <set>#include <tuple>#define MAX 2100000000#define inf LONG_MAXusing namespace std;using ll = long long;using ull = unsigned long long;vector<int>v;int arr[8001];int main() {ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);int n;cin >> n;int sum = 0;for (int i = 0; i < n; i++) {int a;cin >> a;sum += a;v.push_back(a);arr[a + 4000]++;}sort(v.begin(), v.end());int cnt_max = 0;int ans;bool check = false;for (int i = 0; i < 8001; i++) {if (arr[i] == 0)continue;if (cnt_max < arr[i]) {check = false;cnt_max = arr[i];ans = i-4000;}else if (cnt_max == arr[i]) {if (check)continue;check = true;ans = i - 4000;}}cout << (int)round((double)(sum)/n) << '\n';cout << v[n/2] << '\n';cout << ans << '\n';cout << v[n - 1] - v[0] << '\n';return 0;}cs '백준 문제' 카테고리의 다른 글
백준 18111 (마인크래프트) c++ (0) 2022.07.21 백준 1874 (스택 수열) c++ (0) 2022.07.20 백준 2869 (달팽이는 올라가고 싶다) c++ (0) 2022.07.14 백준 10989 (수 정렬하기 3) c++ (0) 2022.07.12 백준 1436 영화감독 숌 c++ (0) 2022.07.11