ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 21737번 SMUPC계산기
    Algorithm Study/Python 2021. 5. 28. 02:24

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

     

    21737번: SMUPC 계산기

    SMUPC를 기념하기 위해 ALGOS와 DSC Sookmyung에서는 SMUPC의 각 글자로 계산이 이루어지는 계산기를 만들었다. 가은이와 혜민이는 이 계산기와 같은 방식으로 작동하는 프로그램을 만들고자 한다. 가은

    www.acmicpc.net

     

    문제

    SMUPC를 기념하기 위해 ALGOS와 DSC Sookmyung에서는 SMUPC의 각 글자로 계산이 이루어지는 계산기를 만들었다. 가은이와 혜민이는 이 계산기와 같은 방식으로 작동하는 프로그램을 만들고자 한다. 가은이와 혜민이는 몇 가지 계산 작업을 통해 SMUPC에 해당하는 각 기호가 아래의 표와 같이 동작함을 밝혀낼 수 있었다.

    알파벳  S   M   U   P   C 
      해당 수식           -                 *         /
       (정수 몫   
    나눗셈)
            +         여태까지의
    계산 결괏값
    반환

    SMUPC 계산기는 기존의 사칙연산 방식과는 다르게 앞에서부터 순서대로 계산이 이루어진다. 단, 이 계산기에서 음수를 양수로 나누는 경우는 C++14의 기준을 따른다. 이는 음수에 -1을 곱해 양수로 바꾼 뒤 몫을 취하고, 그 몫에 -1을 곱한 것과 같다. 예를 들어, 5/3=1, (−5) /3=−1 로 계산된다. 더불어 SMUPC 계산기에 입력하는 수식은 다음과 같은 규칙을 따라야 한다고 한다.

    • 수식은 0부터 9까지의 숫자와 SMUPC의 알파벳만을 포함할 수 있다.
    • 수식은 수로 시작해야 하며, 알파벳으로 끝나야 한다.
    • 수식에 음수를 입력할 수 없다.
    • 수식에 입력하는 수는 0으로 시작할 수 있다.
    • 알파벳 C로 계산 결괏값을 반환한 후에 추가적인 계산을 원한다면 알파벳 기호를 추가적으로 사용하여 입력을 이어나가야 한다.
    • 알파벳 SMUP는 서로 연속해서 입력할 수 없으며 알파벳 SMUP을 입력한 직후 다른 수의 입력 없이 알파벳 C를 바로 입력할 수 없다.

    SMUPC 계산기와 같은 작업을 수행할 수 있는 프로그램을 작성하여라.

     

    입력

    첫째 줄에 수식에 들어갈 기호의 개수 N(1≤N≤500000)이 주어진다.

    둘째 줄에 N개의 기호가 사용된 수식이 주어진다. 수식의 길이는 1000000을 넘지 않는다. 단, 계산 도중 입력되는 수나 계산 결괏값의 범위는 −231 이상 231−1 이하이다. 더불어 어떤 수를 0으로 나누는 경우는 존재하지 않는다.

     

    출력

    알파벳 C가 나올 때마다 여태까지의 계산 결과 값을 띄어쓰기 간격으로 출력하도록 한다. 알파벳 C가 한번도 나오지 않을 경우 NO OUTPUT을 출력한다.

     

     

    풀이

    단순 입력을 받아서 계산하는 문제이기 때문에 주어진 조건대로 구현하였다.

    def calcul(num1, op, num2):
        if op == 'S':
            temp = num1 - num2
        elif op == 'M':
            temp = num1 * num2
        elif op == 'U':
            temp = num1 // num2
        elif op == 'P':
            temp = num1 + num2
        return temp

    SMUP에 대하여 사칙연산을 하는 함수를 구현했다.

     

    for i in expression :
        if i == 'S' or i == 'M' or i == 'U' or i == 'P' or i == 'C':
            if temp:
                exp.append(int(temp))
                temp = ''
            exp.append(i)
        else :
            temp += i

    input이 문자열 하나로 들어오기 때문에 숫자와 연산자로 구분하여 리스트에 저장했다.

     

    if 'C' not in exp :
        print('NO OUTPUT')
    else :
        while True :
            num1 = exp.popleft()
            op = exp.popleft()
            N -= 1
            
            # C인 경우에는 계속 출력
            while op == 'C':
                print(num1 , end=' ')
                # 연산자의 갯수를 체크하여 연산자가 0개가 되면 종료
                if N <= 0:
                    break
                op = exp.popleft()
                N -= 1
            if N <= 0 :
                break
            num2 = exp.popleft()
            exp.appendleft(calcul(num1, op, num2))

    C가 없는 경우에는 출력하지 않기 때문에 리스트에 C가 있는지 체크해서 없다면 연산하지 않게 구성하고
    나머지 경우에 숫자와 연산자를 pop해서 C인 경우에는 계속 출력하였다.

    C가 아닌 경우에는 calcul함수를 이용하여 계산하고 다시 deque에 넣어주는 방식으로 구현하였다.
    종료 조건이 조금 복잡하게 구성되어 있는데 연산자의 갯수만큼만 연산하고 종료한다.

    예제에 대해서는 모두 통과하였지만 틀렸다고 나와서 체크해보니 //연산이 음수에 대해서는 다른 값이 나왔다.

    -16 // 5도 -3이 나와야하지만 -4가 나오는 것이다.

        elif op == 'U':
            if num1 < 0:
                num1 *= -1
                temp = num1 // num2
                temp *= -1
            else :
                temp = num1 // num2

    U에 대한 연산을 변경해주었더니 통과하였다.

     

     

    전체 코드

    import sys
    from collections import deque
    
    
    N = int(sys.stdin.readline().strip())
    expression = list(sys.stdin.readline().strip())
    flag = 0
    exp = deque()
    temp = ''
    for i in expression :
        if i == 'S' or i == 'M' or i == 'U' or i == 'P' or i == 'C':
            if temp:
                exp.append(int(temp))
                temp = ''
            exp.append(i)
        else :
            temp += i
    
    def calcul(num1, op, num2):
        if op == 'S':
            temp = num1 - num2
        elif op == 'M':
            temp = num1 * num2
        elif op == 'U':
            if num1 < 0:
                num1 *= -1
                temp = num1 // num2
                temp *= -1
            else :
                temp = num1 // num2
        elif op == 'P':
            temp = num1 + num2
        return temp
    
    if 'C' not in exp :
        print('NO OUTPUT')
    else :
        while True :
            num1 = exp.popleft()
            op = exp.popleft()
            N -= 1
            while op == 'C':
                print(num1 , end=' ')
                if N <= 0:
                    break
                op = exp.popleft()
                N -= 1
            if N <= 0 :
                break
            num2 = exp.popleft()
            exp.appendleft(calcul(num1, op, num2))
    

    'Algorithm Study > Python' 카테고리의 다른 글

    [백준] 1012번 유기농 배추  (0) 2021.05.31
    [백준] 12764번 싸지방에 간 준하  (0) 2021.05.29
    [백준] 1520번 내리막 길  (0) 2021.05.28
    [백준] 1092번 배  (0) 2021.05.28
    [백준] 1254번 팰린드롬 만들기  (0) 2021.05.28

    댓글

From BlackHair