이 문제를 풀 때 두 가지가 좀 껄쩍지근했는데
먼저 산술평균을 구할 때 반올림.
cmath
의 round
함수를 사용해서 해결했다.
두 번째는 최빈값.
중복값도 받으면서 정렬이 되어야 하기에 조금 까다롭게 느껴졌다.
음의 정수가 있어서 인덱스 기반으로 풀기도 좀 지저분할 것 같았다.
일단 vector에 n개를 입력받는 동시에 sum, max, min 값을 계산한다.
입력이 끝나면 vector 오름차순 정렬으로 산술평균, 범위, 중앙값까지 해결완
남은 것은 최빈값인데
최빈값이 여러 개일 경우 두 번째로 작은 값을 출력하라고 했기 때문에
먼저 각 값의 빈도수를 저장할 map
과
최빈값 후보를 담아둘 vector
를 하나 더 만들었다.
정렬된 vector를 돌며 map[값]++
을 해주고
다시 map을 돌며 두 번째 vector에 최빈값들을 업데이트하면 된다.
vector의 size가 1이면 그 값을, 아니면 vector[1]이 출력할 최빈값이다.
1. iterator 로 순회
#include <map>
using namespace std;
map<int, int> m;
...
for (auto it = m.begin(); it != m.end(); it++) {
cout << it->first << " " << it->second;
}
2. 범위 기반 순회
#include <map>
using namespace std;
map<int, int> m;
...
for (auto pair : m) {
cout << pair.first << " " << pair.second;
}
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
if (n == 1) {
int num;
cin >> num;
cout << num << "\n" << num << "\n" << num << "\n" << "0";
return 0;
}
vector<int> v(n);
int sum = 0;
int maxi = -4001;
int mini = 4001;
for (int i = 0; i < n; i++) {
cin >> v[i];
sum += v[i];
maxi = max(maxi, v[i]);
mini = min(mini, v[i]);
}
sort(v.begin(), v.end());
map<int, int> m;
for (int i = 0; i < n; i++) {
m[v[i]]++;
}
int cnt = 1;
vector<int> v2;
for (auto pair : m) {
if (pair.second == cnt) {
v2.push_back(pair.first);
}
else if (pair.second > cnt) {
v2.clear();
v2.push_back(pair.first);
cnt = pair.second;
}
}
int avg = round(1.0 * sum / n);
int mid = v[n / 2];
int mode = v2.size() == 1 ? v2[0] : v2[1];
int range = maxi - mini;
cout << avg << "\n" << mid << "\n" << mode << "\n" << range;
return 0;
}