ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 2108 c++ 통계학
    STUDY/C++, C#, VB6, PYTHON 2022. 8. 22. 04:47

    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];
    }

     

    댓글

Designed by Tistory.