문제
N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다.
우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다.
예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.
- 1+2+3-4×5÷6
- 1÷2+3+4-5×6
- 1+2÷3×4-5+6
- 1÷2×3-4+5+6
식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.
- 1+2+3-4×5÷6 = 1
- 1÷2+3+4-5×6 = 12
- 1+2÷3×4-5+6 = 5
- 1÷2×3-4+5+6 = 7
N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다.
출력
첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다. 연산자를 어떻게 끼워넣어도 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력만 주어진다. 또한, 앞에서부터 계산했을 때, 중간에 계산되는 식의 결과도 항상 -10억보다 크거나 같고, 10억보다 작거나 같다.
문제 풀이
연산자 끼워넣기 문제는
수열이 주어졌을 때 수와 수 사이에 연산자를 하나씩 넣어
수식을 만들었을 때 만들 수 있는 식의 결과가
최대인 것과 최소인 것을 구하는 것입니다.
이때 수열의 순서는 바꾸면 안되기 때문에
수열은 그대로 놔두고, 연산자 조합을 구해야 합니다.
더하기, 빼기, 곱하기, 나누기 연산자의 개수가
입력으로 주어지므로 각 연산자의 개수가 1개 이상이라면
연산을 수행하도록 해줍니다.
이때, 연산을 한번 수행한 것이므로 연산자의 개수를 한개 빼주고
재귀함수를 이용해 다음 계산할 index와 계산한 값을 넘겨줍니다.
만약 재귀를 모두 수행했다면 다시 연산자의 개수를 돌려놓아줍니다.
만약 넘겨준 index가 n이 되면 모든 연산자를 사용했다는 것이므로
최대와 최소를 구해줍니다.
My Code
n = int(input()) # 수의 개수
array = list(map(int,input().split())) # 수열
add, sub, mul, div = map(int,input().split()) # 각 연산자의 개수
max_value = -1e9 # 초기 최댓값
min_value = 1e9 # 초기 최솟값
def dfs(i, now):
global add, sub, mul, div, max_value, min_value
if i == n: # index가 n이 되면 완료한 것이므로 최대 최소 계산
max_value = max(max_value, now)
min_value = min(min_value, now)
else:
if add > 0: # 더하기 연산자가 1개 이상이면
add -= 1 # 연산할 것이므로 한개 빼주고
dfs(i + 1, now + array[i]) # 다음 연산할 index와 계산 결과 넘겨줌
add += 1 # 모두 완료하면 다시 연산자의 개수 돌려줌
if sub > 0:
sub -= 1
dfs(i + 1, now - array[i])
sub += 1
if mul > 0:
mul -= 1
dfs(i + 1, now * array[i])
mul += 1
if div > 0:
div -= 1
dfs(i + 1, int(now / array[i]))
div += 1
dfs(1, array[0])
print(max_value)
print(min_value)
'백준(Python) 풀이' 카테고리의 다른 글
백준 1182번. 부분수열의 합 (Python / 파이썬) (0) | 2022.04.22 |
---|---|
백준 14889번. 스타트와 링크 (Python / 파이썬) (0) | 2022.04.22 |
백준 1065번. 한수 (Python / 파이썬) (0) | 2022.04.21 |
백준 9012번. 괄호 (Python / 파이썬) (0) | 2022.04.21 |
백준 1541번. 잃어버린 괄호 (Python / 파이썬) (0) | 2022.04.20 |
댓글