알고리즘/백준

[백준 3015] 오아시스 재결합 C++

겜도리도리 2023. 12. 2. 22:32
반응형

문제

백준 3015 오아시스 재결합

 

3015번: 오아시스 재결합

첫째 줄에 줄에서 기다리고 있는 사람의 수 N이 주어진다. (1 ≤ N ≤ 500,000) 둘째 줄부터 N개의 줄에는 각 사람의 키가 나노미터 단위로 주어진다. 모든 사람의 키는 231 나노미터 보다 작다. 사람

www.acmicpc.net

풀이

N = 500,000이므로 O(N^2)으로 푸는 것은 불가능하다.

따라서 Monotonic Stack을 활용한다.

Monotonic Stack

 

[알고리즘] Monotonic Stack

개요 자신보다 큰 값(혹은 작은 값)이 언제 처음 오는지에 대해 구해야 할 때, 가장 쉽게 떠올릴 수 있는 방법은 2중 for 문을 쓰는 것이다. 예를 들어 다음과 같이 숫자가 있다고 할 때 3 4 1 5 2 각

gamedoridori.tistory.com

같은 값이 들어올 수 있으므로 해당 케이스만 추가로 처리해 주면 된다.

 

stack의 원소로는 (value, 연속하는 count)를 사용하였다.

현재 값보다 작은 값들을 모두 뺀 다음, 같은 값이 들어오면 다음과 같은 과정을 거친다.

1. stack을 pop 한다.

2. 같은 값끼리는 모두 볼 수 있다. 원래 stack에 있던 count만큼 VisibleCount를 증가시킨다.

3. stack에 남아 있는 원소가 있을 경우, 이들 중 첫 번째 원소 중에서도, 가장 뒤에 있는 친구만 새로 들어온 값을 볼 수 있다. 따라서 VisibleCount를 1 증가시켜 준다.

 

소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    int N = 0;
    cin >> N;
    // height, sameCount
    stack<pair<intint>> st;
    long long visibleCount = 0;
 
    for (int idx = 0; idx < N; idx++)
    {
        int curHeight = 0;
        cin >> curHeight;
        
        // 현재 값보다 작은 값들 다 뺌
        while (!st.empty() && st.top().first < curHeight)
        {
            visibleCount += st.top().second;
            st.pop();
        }
 
        // 스택 제일 위값 비교
        // 비어있으면 그냥 push
        if (st.empty())
        {
            st.push({ curHeight, 1 });
        }
        // 같으면 계산
        else if (st.top().first == curHeight)
        {
            int tempCount = st.top().second;
            visibleCount += tempCount;
            st.pop();
            if (st.size() >= 1)
                visibleCount++;
 
            st.push({ curHeight, tempCount + 1});
        }
        // 작으면 그냥 push 및 카운트 증가
        else
        {
            st.push({ curHeight, 1 });
            visibleCount++;
        }
    }
 
    cout << visibleCount;
 
    return 0;
}
cs
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 2108] 통계학 C++  (0) 2023.12.23
[백준 1725] 히스토그램 C++  (0) 2023.12.04
[백준 2564] 경비원 C++  (3) 2023.05.30
[백준 4811] 알약 C++  (0) 2023.05.15
[백준 2302] 극장 좌석 C++  (0) 2023.05.11