https://www.acmicpc.net/problem/2108
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
최빈값에서 꽤나 애먹었다.
max_element라는 좋은 녀석을 알게되었다.
이녀석은 값 자체를 반환하는게 아닌, 값의 주소를 반환한다. (iterator 반복자)
그러므로 값을 참조하고싶다면 *를 붙여주도록 하자.
max_element는, 범위 내에서 가장 큰녀석의 첫번째 위치를 반환해준다. (반대로는 min_element가 있다.)
arr = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5} 라는 배열이 있다면
배열안에서 5가 들어있는 첫번째 위치, 즉 arr[4] 에 들어있는 5라는 값의 위치를 반환하는 것이다.
이를 응용한다면.
두번째 최빈값을 찾으려면, 첫번째 최빈값의 + 1 주소부터 다시 찾아 나오는 값이 두번째 최빈값일 것이다.
밑의 소스코드를 보게되면
*highNum != *max_element(highNum + 1, countNum.end()) 가 if문의 조건으로 들어가 있는데
만약 최빈값이 같다면 이라는 조건문이다.
highNum 과 max_element의 값을 대조해야하니
값을 참조하기위해 앞에 *을 붙였고,
int형 이기때문에 highNum + 1 이라 하게되면
highNum + 0x04가 되면서 첫번째 최빈값의 다음 위치부터 시작하는 것이다.
int기 때문에 +1만 해줘도 자동으로 다음 값으로 넘어간다.
나의 VS환경에서
예제중 하나인
1
4000
을 집어 넣게되면
cannot dereference out of range array iterator 디버깅 오류가 나와서
계속 고생을 했다.
1
3999까진 오류가 없는데 4000이 문제...
디버깅돌려보니 3999까지는 array의 7999주소값에 잘 들어가는 모습이보이나
4000은 무조건 에러..
그냥 채점풀이에 넣어봤더니 맞았다고 나온다. 다음에 한 번 다시 보는걸로 하자.
#include <iostream>
#include <algorithm>
#include <vector>
#include <array>
#include <cmath>
#include <functional>
using namespace std;
array<int, 8001> countNum = { 0 };
array<int, 8001>::iterator highIndex;
int avgNum(vector<int> a);
int midNum(vector<int> a);
int unqNum(array<int, 8001> a, array<int, 8001>::iterator b);
int rangeNum(vector<int> a);
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, num, mode;
vector<int> vec;
cin >> N;
for (auto i = 0; i < N; i++)
{
cin >> num;
vec.push_back(num);
countNum[num + 4000]++;
}
cout << avgNum(vec) << "\n";
cout << midNum(vec) << "\n";
cout << unqNum(countNum, highIndex) << "\n";
cout << rangeNum(vec) << "\n";
}
int avgNum(vector<int> a)
{
double sum = 0;
for (int i : a)
sum += i;
return round(sum / a.size());
}
int midNum(vector<int> a)
{
sort(a.begin(), a.end());
int mid = a.size() / 2;
return a[mid];
}
int unqNum(array<int, 8001> countNum, array<int, 8001>::iterator highNum)
{
int unq = 0;
highNum = max_element(countNum.begin(), countNum.end());
if(*highNum != *max_element(highNum + 1, countNum.end()))
unq = (int)(highNum - countNum.begin()) - 4000;
else
unq = (int)(max_element(highNum + 1, countNum.end()) - countNum.begin()) - 4000;
return unq;
}
int rangeNum(vector<int> a)
{
sort(a.begin(), a.end());
return a[a.size() - 1] - a[0];
}
'STUDY > Baekjoon' 카테고리의 다른 글
[백준] 1316 c++ 그룹 단어 체커 (0) | 2022.08.25 |
---|---|
[백준] 25304 c++ 영수증 (0) | 2022.08.24 |
[백준] 10814 c++ 나이순 정렬 (0) | 2022.08.21 |
[백준] 11650 c++ 좌표 정렬하기 (0) | 2022.08.21 |
[백준] 10816 c++ 숫자 카드 2 (0) | 2022.08.19 |