article thumbnail image
Published 2023. 1. 13. 20:34

문제 설명

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

 

17299번: 오등큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

www.acmicpc.net

크기가 n인 수열이 주어질 때, 각 원소의 오등큰수를 구하기

오등큰수는 오른쪽에 있으면서 수열에서 등장한 횟수가 큰 수 중에서 가장 왼쪽에 있는 수

그러한 수가 없으면 오큰등수는 -1

 

문제 풀이법

[백준 17298 오큰수] 문제와 매우 유사하다

다른점은 원소의 크기가 아닌, 원소의 횟수를 따로 저장해서 비교해 주어야 한다는 점이다

 

  • 수열을 담을 vector<int> v
  • monotone stack을 활용할 stack<int> s
  • 원소의 등장 횟수를 담을 vector<int> cnt
    • 이때 미리 1000001만큼 0으로 초기화 해주어야 한다 (원소의 최댓수가 1000000이므로)
  • 답을 담을 vector<int> ans

이 4개가 필요하다

 

  • 수열을 입력 받으면서 v에 담고, cnt[v[i]] + 1를 해준다
  • 맨 뒤에서부터 스택에 대해 내림차순(가장 큰 수가 먼저 들어감) 연산을 한다
    • 만일 스택이 비어있다면 오등큰수가 없으므로 바로 ans에 -1을 넣는다
    • 스택이 비어있지 않다면, 스택이 비지 않거나, 스택의 top이 나온 횟수가 원소가 나온 횟수보다 크지 않을 때 까지 pop하며 while문을 돈다
    • 다 돌았을 때, 비어있다면 오큰등수가 없는 것이므로 ans에 -1을 넣는다
    • 비어있지 않다면 스택의 top이 나온 횟수가 오큰등수이므로 ans에 넣는다
  • 연산이 끝나면 ans의 값을 출력한다

 

 

소스 코드

#include <iostream>
#include <stack>
#include <vector>

using namespace std;

int main()
{   
    int n;
    cin >> n;
    
    stack<int> s;
    vector<int> v(n + 1, 0);
    vector<int> cnt(1000001, 0);
    vector<int> ans(n + 1, 0);
    for (int i = 1; i <= n; i++)
    {
        int tmp;
        cin >> tmp;
        v[i] = tmp;
        cnt[tmp]++;
    }
    
    for (int i = n; i > 0; i--)
    {
        if (!s.empty())
        {
            while (!s.empty())
            {
                if (cnt[s.top()] > cnt[v[i]])
                    break;
                s.pop();
            }
            if (s.empty())
                ans[i] = -1;
            else    
                ans[i] = s.top();
        }
        else
            ans[i] = -1;
            
        s.push(v[i]);
    }
    
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    return 0;
}

'Algorithm Study' 카테고리의 다른 글

[백준] 2164 카드2  (0) 2023.01.17
[백준] 10845 큐, 18258 큐2  (0) 2023.01.16
[백준] 17298 오큰수  (0) 2023.01.13
[백준] 6198 옥상 정원 꾸미기  (0) 2023.01.13
[백준] 2493 탑  (0) 2023.01.12
복사했습니다!