https://www.acmicpc.net/problem/1541
잃어버린 괄호 성공
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
출처
- 문제를 번역한 사람: baekjoon
- 잘못된 조건을 찾은 사람: windflower
+와 -가 섞인 식에서 괄호를 쳐서 최솟값을 얻으려면 어떻게 해야 할까?
-> 최대한 큰 수를 뺀다
-> '-' 기호 기준으로 나누면, 예를 들어 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배열의 숫자를 빼면 최솟값 구하기 성공
소감: 답을 보면 참 쉬운 문제인데, 난 왜 단순무식하게 풀어서 복잡해질까? ㅠㅅ ㅠ 문제를 어떻게 풀면 되는지 미리 생각하고 코드를 구현하자.!! 😥
'알고리즘 > 백준' 카테고리의 다른 글
백준 1946 신입사원 파이썬 그리디 알고리즘 (0) | 2022.12.27 |
---|---|
1026번 보물 파이썬 그리디 알고리즘 (0) | 2022.12.26 |
백준 10757번 큰 수 문제 A+B (0) | 2022.11.29 |
백준 1018번 파이썬풀이 (0) | 2022.11.11 |
백준 11047번 (0) | 2022.10.12 |