본문 바로가기
PS 문제 풀이/Baekjoon

[BOJ] 백준 3425 고스택

by 까망 하르방 2021. 2. 22.
반응형

출처: https://www.acmicpc.net/problem/3425

 Input 

DUP

MUL

NUM 2

ADD

END

3

1

10

50

 

NUM 1

NUM 1

ADD

END

2

42

43

 

NUM 600000000

ADD

END

3

0

600000000

1

 

QUIT

  

 Output 

3

102

2502

 

ERROR

ERROR

 

600000000

ERROR

600000001

알려져 있는 스택을 변형한 문제로 입력 횟수, 데이터 범위, 예외 처리 등

코드 최적화가 필요한 문제입니다.

 

Sample Case 분석

DUP: 스택의 첫번째 숫자를 복사해서 저장  MUL: 스택의 첫번째 숫자와 두번째 숫자를 곱해서 저장

→ NUM 2: 숫자 2를 스택에 저장 → ADD: 첫번째 숫자와 두번째 숫자를 더합니다.

if) 처음 들어간 숫자 = A 일때, (A × A) + 2 결과를 얻어냅니다.

stack = [1] → stack = [1 1] → stack = [1] → stack = [1 2] → stack = [1 3]

stack = [10] → stack = [10 10] → stack = [100] → stack = [100 2] → stack = [102]

stack = [50] → stack = [50 50] → stack = [2500] → stack = [2500 2] → stack = [2502]

 


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#define MAX 1000000000
using namespace std;
typedef long long LL;
 
stack<LL> st;
vector<string> cmd;
vector<LL> NUM_X;
int n, first, errorCheck, NUM_top;
LL x;
string str;
 
void init() {
    errorCheck = 0;
    NUM_X.clear();
    cmd.clear();
}
 
int NUM(LL x) {
    st.push(x);
    return 0;
}
 
int POP() {
    if (st.empty())
        return 1;
    st.pop();
    return 0;
}
 
int INV() {
    if (st.empty())
        return 1;
 
    LL x = -(st.top());
    st.pop();
    st.push(x);
    return 0;
}
 
int DUP() {
    if (st.empty())
        return 1;
 
    st.push(st.top());
    return 0;
}
 
int SWP() {
    if (st.empty())
        return 1;
 
    LL x = st.top();
    st.pop();
 
    if (st.empty()) {
        return 1;
    }
 
    LL y = st.top();
    st.pop();
    st.push(x); st.push(y);
    return 0;
}
 
int ADD() {
    if (st.empty())
        return 1;
 
    LL x = st.top();
    st.pop();
 
    if (st.empty())
        return 1;
 
    x += st.top();
    st.pop();
    st.push(x);
 
    return 0;
}
 
int SUB() {
    if (st.empty())
        return 1;
 
    LL x = st.top();
    st.pop();
 
    if (st.empty())
        return 1;
 
    x = st.top() - x;
    st.pop();
    st.push(x);
 
    return 0;
}
 
int MUL() {
    if (st.empty())
        return 1;
 
    LL x = st.top();
    st.pop();
 
    if (st.empty())
        return 1;
 
    x *= st.top();
    st.pop();
    st.push(x);
 
    return 0;
}
 
int DIV() {
    int neg = 0;
    if (st.empty())
        return 1;
    LL x = st.top();
    if (x < 0) ++neg;
    st.pop();
 
    if (st.empty())
        return 1;
    LL y = st.top();
    if (y < 0) ++neg;
 
    if (x == 0)
        return 1;
    x = y / x;
    if (neg == 1) x = -(abs(x));
    else x = abs(x);
 
    st.pop();
    st.push(x);
    return 0;
}
 
int MOD() {
    int neg = 0;
 
    if (st.empty())
        return 1;
 
    LL x = st.top();
 
    st.pop();
 
    if (st.empty())
        return 1;
 
    LL y = st.top();
    if (y < 0) ++neg;
 
    if (x == 0)
        return 1;
 
    x = y % x;
    if (neg == 1) x = -(abs(x));
    else x = abs(x);
 
    st.pop();
    st.push(x);
 
    return 0;
}
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
 
    while (1) {
        init();
        while (1) { // 명령어 입력받기
            cin >> str;
            if (str == "NUM") {
                cin >> x;
                NUM_X.push_back(x);
            }
            else if (str == "QUIT") {
                return 0;
            }
            else if (str == "END") {
                break;
            }
            cmd.push_back(str);
        }
 
        cin >> n;
        while (n--) {
            NUM_top = 0; // NUM 명령어로 들어갈 숫자들의 TOP
            cin >> first;
            st.push(first); // 처음 스택에 들어가 있는 숫자
 
            for (int i = 0; i < cmd.size(); ++i) {
                if (cmd[i] == "NUM") errorCheck = NUM(NUM_X[NUM_top++]);
                else if (cmd[i] == "POP") errorCheck = POP();
                else if (cmd[i] == "INV") errorCheck = INV();
                else if (cmd[i] == "DUP") errorCheck = DUP();
                else if (cmd[i] == "SWP") errorCheck = SWP();
                else if (cmd[i] == "ADD") errorCheck = ADD();
                else if (cmd[i] == "SUB") errorCheck = SUB();
                else if (cmd[i] == "MUL") errorCheck = MUL();
                else if (cmd[i] == "DIV") errorCheck = DIV();
                else if (cmd[i] == "MOD") errorCheck = MOD();
 
                // 연산결과의 절대값이 (10^9)을 초과하는지 확인
                if (!st.empty() && (st.top() > MAX || st.top() < -MAX))
                    errorCheck = 1;
 
                if (errorCheck)
                    break;
            }
            // 에러가 발생하였거나 스택에 원소 1개만 있는 경우가 아닌 경우
            if (errorCheck == 1 || st.size() != 1)
                cout << "ERROR\n";
            else  // 결과 출력
                cout << st.top() << "\n";
            while (!st.empty()) {
                st.pop();
            }
        }
        cout << endl;
    }
}

 

반응형

'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글

[BOJ] 백준 7576 토마토  (0) 2021.02.22
[BOJ] 백준 8979 올림픽  (0) 2021.02.22
[BOJ] 백준 2563 색종이  (0) 2021.02.22
[BOJ] 백준 17825 주사위 윷놀이  (0) 2021.02.22
[BOJ] 백준 17822 원판 돌리기  (0) 2021.02.22

댓글