알고리즘

[BOJ] 1874 스택수열

졔졔311 2023. 5. 24. 21:28
728x90
반응형

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

 

1874번: 스택 수열

1부터 n까지에 수에 대해 차례로 [push, push, push, push, pop, pop, push, push, pop, push, push, pop, pop, pop, pop, pop] 연산을 수행하면 수열 [4, 3, 6, 8, 7, 5, 2, 1]을 얻을 수 있다.

www.acmicpc.net

---------------------------------------------------핵심 알고리즘--------------------------------------------

 

stack

 

---------------------------------------------------풀이----------------------------------------------------

 

제목처럼 스택을 이용하는 문제이다.

 

1~n까지 차례대로 들어온다고 생각했을 때, 들어올 차례의 숫자를 num이라고 한다.

만약 입력받은(출력해야 할) 숫자 cur이 num 이상이면, cur까지 스택에 들어와야 하므로

num부터 cur까지 stack에 push한다.

 

만약 cur < num이면, 이미 스택에 있는 숫자이므로

cur이 나올 때까지 pop한다.

이렇게 찾았을 때 cur이 존재하지 않으면, yes_flag가 false가 되고 종료된다.

 

수열이 정상적으로 만들어졌다면 yes_flag는 true이면서 push와 pop의 합의 개수는 2n개다.

각 숫자마다 stack에 push 한 번, pop 한 번 이루어질 것이기 때문이다.

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

using namespace std;

int main(void){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    stack<int> s;
    vector<char> ans;
    int num = 1;    // 스택에 들어올 차례인 숫자
    bool yes_flag = true;
    for(int i = 1; i <= n; i++){
        int cur;
        cin >> cur;
        if(cur >= num){
            // push
            for(int i = num; i <= cur; i++){
                ans.push_back('+');
                s.push(i);
            }
            num = cur+1;
            // pop
            ans.push_back('-');
            s.pop();
        }
        else{
            yes_flag = false;
            // pop
            while(!s.empty()){
                ans.push_back('-');
                if(s.top() == cur){
                    s.pop();
                    yes_flag = true;
                    break;
                }
                s.pop();
            }
            if(!yes_flag){
                break;
            }
        }
    }
    if(ans.size() != n*2 || !yes_flag){
        cout << "NO\n";
    }
    else{
        for(int i = 0; i < ans.size(); i++){
            cout << ans[i] << "\n";
        }
    }
    return 0;
}

 

---------------------------------------------------후기----------------------------------------------------

 

다음의 programmers에서 푼 문제와 매우 흡사하다.

https://jyejye311.tistory.com/15

다만, push pop 순서에 따라 +/-를 저장해야한다는 점이 다르다.

문제를 코드가 더럽게 푼 것 같긴 한데, 다듬는건 다음에..!

728x90
반응형

'알고리즘' 카테고리의 다른 글

[BOJ] 2164 카드2  (0) 2023.05.24
[BOJ] 1978 소수 찾기  (1) 2023.05.24
[programmers] 혼자 놀기의 달인  (0) 2023.05.20
[programmers] 연속 부분 수열 합의 개수  (0) 2023.05.20
[programmers] 고고학 최고의 발견  (1) 2023.05.19