728x90
http://www.acmicpc.net/problem/3425
# 조건
- 창영이는 스택을 조금 변형해서 고스택을 만듦
- 숫자만 저장 가능하며 아래 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
'ALGORITHM > 자료구조' 카테고리의 다른 글
[백준 1918번] 파이썬 - 후위 표기식 (0) | 2022.12.08 |
---|---|
[백준 5639번] 파이썬 - 이진 검색 트리 (0) | 2022.12.08 |
[백준 1202번] 파이썬 - 보석 도둑 (0) | 2022.12.01 |
[백준 1043번] 파이썬 - 거짓말 (0) | 2022.11.30 |
[백준 11286번] 파이썬 - 절댓값 힙 (0) | 2022.10.20 |