[BOJ] 17299 오등큰수 C++ 문제풀이 & 소스코드

반응형
반응형

Info

난이도 : GOLD3

유형 : DataStructure

https://www.acmicpc.net/problem/17299

소스코드 : https://github.com/novvvv/PS/blob/main/BOJ/2025/C++/17299.cpp


Solve

문제분석

F(Ai) - Ai가 수열A에서 등장한 횟수. 

Ai의 오등큰수 - 오른쪽에 있으면서 수열 A에서 등장한 횟수가 F(Ai)보다 큰 수 중 가장 왼쪽에 있는 수. 그러한 수가 없으면 오등큰수는 -1

 

a[] : 크기가 n인 수열

freq[] : ai가 몇 번 등장했는지 빈도를 저장할 수열

ngf[] : 각 원소의 오등큰수 정보를 저장할 수열 

int a[max_val], freq[max_val], ngf[max_val];

 

수열의 정보를 입력함과 동시에 해당 원소의 빈도를 증가시킨다.

    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        freq[a[i]]++;
    }

 

수열 a를 반대로 순회하여 원소를 차례로 스택에 집어넣는다. 

만약 스택이 비어있지 않고, 스택의 최상단에 있는 원소의 빈도 (freq[stk.top()]) 보다 현재 넣으려고 하는 원소의 빈도 (freq[a[i]]) 보다 작거나 같다면 스택에서 원소를 제거한다.

 

1 1 2 [3 4 2 1] 을 예시로 들어보면

원소 3의 경우 빈도가 1이고, 원소 4 또한 빈도가 1이다. 따라서 원소 4를 스택에서 제거한다. 

 

1 1 2 [3 2 1] 

원소 3의 빈도 (1) 보다 원소 2의 빈도 (2)가 더 크기에 원소 3의 ngf는 스택의 최 상단인 2가 된다.

왜냐하면 ngf의 정의를 보면 3보다 우측에 존재하면서 빈도가 3보다 크고 가장 왼쪽에 존재하는 원소는 2이기 때문이다. 

* 스택의 최상단에 존재하는 원소는 항상 i번째 원소의 ngf를 만족한다. 

 

스택이 비어있다면 오른쪽에 빈도가 더 높은 수가 없다는 뜻이니 ngf를 -1로 초기화한다. 

 

    stack<int> stk;
    for (int i = n - 1; i >= 0; i--) {
        while(!stk.empty() && freq[stk.top()] <= freq[a[i]]) stk.pop();
        if (stk.empty()) ngf[i] = -1; // 스택이 비어있다? -> 오른쪽에 빈도가 더 높은 수가 없다. (-1)
        else ngf[i] = stk.top();
        stk.push(a[i]);
    }

 

반응형

댓글

Designed by JB FACTORY