728x90

http://www.acmicpc.net/problem/3425

 

3425번: 고스택

각각의 입력값에 대해서, 해당하는 프로그램을 수행한 뒤, 출력값을 출력하면 된다. 출력값이란 스택에 저장되어 있는 숫자이다. 만약, 프로그램 에러가 발생하거나, 모든 수행이 종료됐을 때

www.acmicpc.net

 

 

# 조건

  • 창영이는 스택을 조금 변형해서 고스택을 만듦
  • 숫자만 저장 가능하며 아래 10가지 연산을 수행할 수 있다
  • 편의상 스택의 가장 위에 저장된 수 첫 번째
    • NUM X: X를 스택의 가장 위에 저장한다. (0 ≤ X ≤ 109)
    • POP: 스택 가장 위의 숫자를 제거한다.
    • INV: 첫 번째 수의 부호를 바꾼다. (42 -> -42)
    • DUP: 첫 번째 숫자를 하나 더 스택의 가장 위에 저장한다.
    • SWP: 첫 번째 숫자와 두 번째 숫자의 위치를 서로 바꾼다.
    • ADD: 첫 번째 숫자와 두 번째 숫자를 더한다.
    • SUB: 첫 번째 숫자와 두 번째 숫자를 뺀다. (두 번째 - 첫 번째)
    • MUL: 첫 번째 숫자와 두 번째 숫자를 곱한다.
    • DIV: 첫 번째 숫자로 두 번째 숫자를 나눈 몫을 저장한다. 두 번째 숫자가 피제수, 첫 번째 숫자가 제수이다.
    • MOD: 첫 번째 숫자로 두 번째 숫자를 나눈 나머지를 저장한다. 두 번째 숫자가 피제수, 첫 번째 숫자가 제수이다.
 
  • 이항 연산자의 경우 - 첫 번째 숫자가 오른쪽에 있는 수, 두 번째 숫자가 왼쪽에 있는 수
  • 또, 연산을 수행하기 전 두 숫자를 모두 스택에서 제거한 뒤, 결과를 다시 스택에 저장하는 것
  • 숫자가 부족해 연산 수행할 수 없을 때, 0으로 나눴을 때, 연산 결과의 절댓값이 10^9가 넘어갈 때는 모두 프로그램 에러
  • 나눗셈의 피연산자에 음수가 있을 때는, 그 수를 절댓값을 씌운 뒤 계산한 후 몫과 나머지의 부호는 아래와 같이 결정
    • 피연산자중 음수가 한 개일때는 몫의 부호가 음수
    • 이 경우 제외하면 몫의 부호는 항상 양수
    • 나머지의 부호는 피제수의 부호와 같다.
    • 따라서 13 div -4 = -3, -13 mod 4 = -1, -13 mod -4 = -1
  • 에러가 발생했을 경우, 현재 프로그램의 수행을 멈추고, 그 다음 어떤 명령도 수행 xxx
 

입력

  • 기계 여러 대의 설명
  • 각 기계의 설명은 프로그램과 입력영역으로 나누어져 있다.
  • 각 명령은 대문자 알파벳 3글자
  • NUM의 경우에는 명령어 다음에 숫자가 주어진다.
  • 각 프로그램은 END가 나오면 끝난다.
  • QUIT이 나오면 다음 기계 설명이 없다는 뜻
 

# 접근 방법 및 Solution

  • 조건을 잘 읽고 그대로 구현해주면 될 것 같다.
  • 프로그램 에러가 나는 것을 try : except를 이용하여 ERROR를 출력하는데
  • 모든 수행이 종료됐을 때 스택에 저장되어 있는 숫자가 1개가 아닐 때도 ERROR를 출력해주어야 한다.
  • 우선 명령어를 다 받아 준 후, 숫자가 처음 나온 시점 부터 명령어를 따라 각 숫자를 연산해주면 된다.
  • isdigit을 활용하여 숫자 판별
import sys  
sys.stdin = open('input.txt')  
input = sys.stdin.readline  
  
# 종료 조건  
stack = []  
  
# 결과 저장  
result = []  
# 명령어 저장  
instructor = []  
  
  
def NUM(start):  
    global flag,result,stack  
    a,b = start.split()  
    stack.append(int(b))  
    return stack  
  
def POP():  
    global flag,result,stack  
    if stack:  
        stack.pop()  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
def INV():  
    global flag,result,stack  
    if stack:  
        stack[-1] = -stack[-1]  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def DUP():  
    global flag,result,stack  
    if stack:  
        stack.append(stack[-1])  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def SWP():  
    global flag,result,stack  
    if len(stack) >= 2:  
        a = stack[-1]  
  
        stack[-1] = stack[-2]  
        stack[-2] = a  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def ADD():  
    global flag,result,stack  
    if len(stack) >= 2:  
        a,b = stack.pop(), stack.pop()  
        if abs(a+b) > 10**9:  
            result.append('ERROR')  
            flag = False  
            return flag  
        stack.append(a+b)  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def SUB():  
    global flag,result,stack  
    if len(stack) >= 2:  
        a,b = stack.pop(), stack.pop()  
        if abs(b-a) > 10**9:  
            result.append('ERROR')  
            flag = False  
            return flag  
        stack.append(b-a)  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def MUL():  
    global flag,result,stack  
    if len(stack) >= 2:  
        a,b = stack.pop(), stack.pop()  
        if abs(b*a) > 10**9:  
            result.append('ERROR')  
            flag = False  
            return flag  
        stack.append(a*b)  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
def DIV():  
    global flag,result,stack  
    if len(stack) >= 2:  
        a,b = stack.pop(), stack.pop()  
        if a == 0:  
            result.append('ERROR')  
            flag = False  
            return flag  
        else:  
            c = abs(b) // abs(a)  
            if abs(c) > 10**9:  
                result.append('ERROR')  
                flag = False  
                return flag  
            elif b < 0 and a < 0:  
                stack.append((abs(b) // abs(a)))  
            elif b<0 or a<0:  
                stack.append(-(abs(b)//abs(a)))  
            else:  
                stack.append(b//a)  
  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
  
def MOD():  
    global flag,result,stack  
  
    if len(stack) >= 2:  
        a, b = stack.pop(), stack.pop()  
  
        if a == 0:  
            result.append('ERROR')  
            flag = False  
            return flag  
        else:  
            c = abs(b) % abs(a)  
  
            if c > 10**9:  
                result.append('ERROR')  
                flag = False  
                return flag  
            if b < 0:  
                stack.append(-(abs(b) % abs(a)))  
            else:  
                stack.append(abs(b) % abs(a))  
  
    else:  
        result.append('ERROR')  
        flag = False  
        return flag  
  
  
  
while True:  
    inst = input().rstrip()  
    if inst:  
        if inst[0] == 'Q':  
            break  
    else:  
        stack = []  
        instructor = []  
        continue  
    # 프로그램 수행 횟수 들어오면 수행 시작  
    if inst.isdigit():  
        pro = int(inst)  
        for i in range(pro):  
            flag = True  
            num = int(input())  
            stack.append(num)  
            for j in instructor:  
                # 에러 발생했다면 종료  
                if not flag:  
                    stack=[]  
                    break  
  
                # 각 명령어에 따른 실행 할 명령함수  
                if j[0] == 'N':  
                    NUM(j)  
  
                elif j[0] == 'P':  
                    POP()  
  
                elif j[0] == 'I':  
                    INV()  
  
                elif j[0] == 'S':  
                    if j[1] == 'W':  
                        SWP()  
                    else:  
                        SUB()  
                elif j[0] == 'A':  
                    ADD()  
  
                elif j[0] == 'S':  
                    SUB()  
  
                elif j[0] == 'M':  
                    if j[1] == 'U':  
                        MUL()  
                    else:  
                        MOD()  
  
                elif j[0] == 'D':  
                    if j[1] == 'U':  
                        DUP()  
                    else:  
                        DIV()  
  
                elif j[0] == 'E':  
                    if len(stack) == 1:  
                        result.append(stack[0])  
                    else:  
                        result.append('ERROR')  
                    stack = []  
  
                      
        result.append(' ')  
  
    # 아니라면 명령어 추가  
    else:  
        instructor.append(inst)  
  
  
print(*result[:-1], sep='\n')
  • 함수를 여러 개 해주었지만, 하나의 함수안에서 명령어를 순회하며 풀어주는게 더 깔끔해보인다.
  • 몫과 나머지를 구하는 함수의 조건을 제대로 파악하지 못하여 계속 틀렸다..
728x90