본문 바로가기

알고리즘/백준 문제 풀이

[Python] 30855번 Fraction

728x90

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


 

24/11/22

 

 

ICPC문제 중 흔치 않은 파이썬 친화적인 문제다.


 

문제 접근 방식:

 

 

파이썬에서는 fractions 모듈이 존재한다. 이 모듈은 유리수를 정확하게 저장해준다.

 

분모와 분자는 자동적으로 약분을 해서 저장된다.

 

문제는 굉장히 간단하다. $(a, b, c)$의 형태로 주어질 때, $a + b/c$의 값을 기약 분수로 출력하는 것이 목적이다.

 

$a, b, c$는 숫자 혹은 또 다른 $(a, b, c)$형태의 괄호 문자열이 될 수 있다.

 

스택을 통해 해결할 수 있다.

 

예외를 처리하는 부분이 많은데, 그냥 raise문을 통해 Error를 띄우도록 하면 처리가 간편해진다.

 

예를 들어, 열린 괄호가 있는데 닫히지 않는다라던지, 맨 마지막에 숫자만 남아야 하는데 숫자가 안남는다던지, 닫힌 괄호가 나올 때 세 숫자를 빼야하는데, 스택에 세 숫자가 아니라 두 숫자 혹은 네 숫자가 있다던지 등등을 모두 Except로 따로 빼면 처리하기 간편하다.


아래는 내가 위의 접근 방식과 같이 작성한 파이썬 코드이다. 더보기를 누르면 확인할 수 있다.

더보기
# 30855번 Fraction
# 스택, 파싱
import sys
input = sys.stdin.readline
from fractions import Fraction

def solve():
    N = int(input())
    S = input().rstrip().split()
    left = 0
    stack = []
    try:
        for i in range(N):
            char = S[i]
            if char == '(':
                left += 1
                stack.append('(')
            elif char == ')':
                left -= 1
                c, b, a = stack.pop(), stack.pop(), stack.pop()
                k = a + b/c
                if stack[-1] != '(':
                    raise Error
                stack.pop()
                stack.append(k)
            else:
                a = Fraction(char)
                stack.append(a)
        if len(stack) == 1:
            ans = stack.pop()
            print(ans.numerator, ans.denominator)
        else:
            raise Error
    except:
        print(-1)
        return
      
solve()