공부하기/백준

[Python] 백준 풀기 1541 - 잃어버린 괄호

XEV 2022. 10. 9. 20:49

파이썬 백준 1541번

실버2

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

 

1541번: 잃어버린 괄호

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다

www.acmicpc.net

 

 

 

 

문제 보기

분류: 그리디 알고리즘, 수학, 문자열, 파싱

 

 

 

문제 풀기

괄호를 적절히 섞어 최소가 되는 값을 찾기 위한 문제이기에 최소가 되기 위해서는 - 항이 많아져야 한다. 이를 위해 수식에서 - 가 나타나면 괄호의 시작으로 하여 모든 + 들을 거쳐 다음 - 가 나오기 전까지 묶어 주면 된다. 이 말인즉슨, - 문자를 기준으로 분리하여 개별적 묶음을 형성하고 첫 묶음은 무조건 + 로 시작하니 이 묶음의 합에서 나머지 - 로 시작하는 묶음들을 차례로 빼주는 식으로 생각을 하였다.

 

초기 풀이에서는 0 으로 시작하는 숫자 (00009) 를 생각지 않고 문자식들을 바로 계산해버릴 수 있는 eval() 함수를 적용하여 풀어 보았는데 예제 00009 에서 에러가 나타나 str -> int 로 바꾸는 과정을 쓰게 되었다.

 

str(inputdata().strip()) 으로 입력 문자 그대로 저장하여 arithmetic_str.split('-') 를 사용하여 문자 "-" 기준으로 분리해 리스트 형태로 저장하였다. 그리고 for loop 를 돌리면서 0 으로 시작하는 숫자(str) 을 계산이 가능한 형태로 바꿔주기 위해 int 로 바꿔주었고, 이를 실행하는데 "+" 문자가 포함되어있어 "+" 에 대해 분리를 해주었다. list(map(int, arithmetic_ls[i].split('+')))  

이렇게 정제된 리스트들의 첫 번째 값은 항상 양의 값을 갖기에 total_sum = sum(ari_temp_ls) 에 초기값으로 정해지고 그 뒤에 나오는 리스트 원소들은 - 를 달고 있는 괄호 안의 값들이기 때문에 total_sum -= sum(ari_temp_ls) 로 모두 빼주게 된다.

 

 

 

코드 보기

import sys
inputdata = sys.stdin.readline

arithmetic_str = str(inputdata().strip())
arithmetic_ls = arithmetic_str.split('-')           # 최솟값을 구하기 위해 - 연산자로 나누어 리스트 생성

# print(arithmetic_ls)            #

total_sum = 0
for i in range(len(arithmetic_ls)):
    ari_temp_ls = list(map(int, arithmetic_ls[i].split('+')))           # 처음 0으로 시작하는 문자를 해결하기 위한 + 연산자로 분리 작업 및 int 로 변환
    
    # print(ari_temp_ls)          #
    
    if i == 0:
        total_sum = sum(ari_temp_ls)
    else:
        total_sum -= sum(ari_temp_ls)

print(total_sum)

 

 

 

추가 하기

 - 0 으로 시작하는 숫자를 배제했을 때 쓴 코드

import sys
inputdata = sys.stdin.readline

arithmetic_str = str(inputdata().strip())
# arithmetic_ls = list(map(str, inputdata().split('-')))

arithmetic_ls = arithmetic_str.split('-')
print(arithmetic_ls)

total_sum = 0
for i in range(len(arithmetic_ls)):
    if i == 0:
        total_sum = eval(arithmetic_ls[0])
    else:
        total_sum -= eval(arithmetic_ls[i])

print(total_sum)

문자(str) 형태의 식을 그대로 계산해 주는 함수 eval() 의 존재를 확인할 수 있었다.

 

 

 - 제출 코드의 작동 방식을 쉽게 이해하기 위해 print() 함수 추가 및 그 출력 결과

import sys
inputdata = sys.stdin.readline

arithmetic_str = str(inputdata().strip())
arithmetic_ls = arithmetic_str.split('-')           # 최솟값을 구하기 위해 - 연산자로 나누어 리스트 생성

print(f'arithmetic_ls: {arithmetic_ls}')            #

total_sum = 0
for i in range(len(arithmetic_ls)):
    ari_temp_ls = list(map(int, arithmetic_ls[i].split('+')))           # 처음 0으로 시작하는 문자를 해결하기 위한 + 연산자로 분리 작업 및 int 로 변환
    
    print(f'ari_temp_ls: {ari_temp_ls}')          #
    
    if i == 0:
        total_sum = sum(ari_temp_ls)
    else:
        total_sum -= sum(ari_temp_ls)

print(total_sum)



# 55+50-40+30-30

# arithmetic_ls: ['55+50', '40+30', '30']
# ari_temp_ls: [55, 50]
# ari_temp_ls: [40, 30]
# ari_temp_ls: [30]
# 5