본문 바로가기
알고리즘/백준

백준 1541번 파이썬 잃어버린 괄호

by 푸딩코딩 2022. 12. 25.
728x90
반응형

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

 

1541번: 잃어버린 괄호

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

www.acmicpc.net

잃어버린 괄호 성공

 
 
시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 128 MB 58662 30509 24211 51.562%

문제

세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.

그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.

괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.

입력

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

출력

첫째 줄에 정답을 출력한다.

예제 입력 1 복사

55-50+40

예제 출력 1 복사

-35

예제 입력 2 복사

10+20+30+40

예제 출력 2 복사

100

예제 입력 3 복사

00009-00009

예제 출력 3 복사

0

출처

 

+와 -가 섞인 식에서 괄호를 쳐서 최솟값을 얻으려면 어떻게 해야 할까? 

-> 최대한 큰 수를 뺀다 

-> '-' 기호 기준으로 나누면, 예를 들어 55-50+40-10+30의 식은

55, 50+40, 10+30이 된다. 

그리고 이 식들을 빼주면, 최대한 큰 수를 뺄 수 있게 된다. 

따라서 -기준으로 식을 나누어 저장하고, 순서대로 빼준 값을 출력! 

 

생각해보면 쉬운 문제인데, 어떻게 접근했냐면... 

1. 문제에서 0으로 시작하는 숫자가 있다고 하니 일단 문장에서 0으로 시작하는 숫자들을 일반적인 정수로 변환하자.

2. -, + 기호가 있는 인덱스를 저장하자

3. 인덱스를 기준으로 ( ) 괄호를 치고, eval(text)하여 최솟값을 갱신하며 구한다..

 

나름 그리디 알고리즘이라 저렇게 생각했는데, 모범답안을 보니 엄청 꼬아서 풀었다는 것을 알 수 있었다. 

 

 

##숫자 따로, 연산자 따로 입력받기 
text=input()
ind=[-1]
count=(text.count('+')+text.count('-'))

text=text.lstrip("0") #앞에 0지우고 
n=0

for i in range(1,len(text)):
    if(n==count):
        break
    if(text[i]=='0' and text[i-1]=='+') or (text[i]=='0' and text[i-1]=='-'):
        k=i
        j=i
        while(text[k]=='0'):
            k+=1
        text=text[:i]+text[k:]
        n+=1
    ##print(text)
for i in range (len(text)):
    if(text[i]=='+' or text[i]=='-'): 
        ind.append(i)
ind.append(len(text))

if '-' not in text: ## - 기호없으면 그냥 출력
     sum=eval(text) 
else:
    sum=eval(text)
    for i in range (len(ind)-1):
        text=list(text)
        text.insert(ind[i]+1,'(')
        for j in range (i+2,len(ind)):
            text.insert(ind[j]+1,')')
            text="".join(text) ##문자열화
            tmp=eval(text)
            if sum>tmp: sum=tmp
            text=list(text)
            text.remove(')')
        text=list(text)
        text.remove("(")
print(sum)

기존에 작성한 코드다.

예제는 모두 실행이 잘 되나, 10009- 00228 +933과 같이 중간에 0으로 시작하는 숫자가 있으면 범위 에러가 뜬다. 

 

text=input().split('-')
num=[]
for i in text:
    sum=0
    a=i.split('+')
    for j in a:
        sum+=int(j)
    num.append(sum)
sum=num[0]
for i in range (1, len(num)):
    sum-=num[i]
print(sum)

새로 작성한 코드! 

-기준으로 나누어 text배열에 저장, 

text배열에 있는 문장을 +로 나누어, 그것들을 더해 num배열 생성, 

sum=num[0] 설정하고, 거기서 num배열의 숫자를 빼면 최솟값 구하기 성공

 

 

 

 

소감: 답을 보면 참 쉬운 문제인데, 난 왜 단순무식하게 풀어서 복잡해질까? ㅠㅅ ㅠ 문제를 어떻게 풀면 되는지 미리 생각하고 코드를 구현하자.!!  😥

728x90
반응형