[문제]
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개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.
[나의 풀이]
from itertools import permutations
# 입력값 3줄
N = int(input())
A = list(map(int, input().split()))
add, sub, multi, div = map(int, input().split())
# 연산자 입력 받은 것을 N-1개의 배열로 각각의 연산자의 갯수에 맞춰 넣어준다.
operation = []
operation += ['+']*add
operation += ['-']*sub
operation += ['*']*multi
operation += ['/']*div
# permutations 라는 것을 통해 연산자의 모든 경우의 수를 구한다(순열 -> 순서 상관 있음), set을 통해 중복 값 제거
operation_list = list(set(permutations(operation)))
# 결과가 항상 -10억 ~ 10억 이라고 했기 때문에, 추후에 결과와 비교할 MAX와 MIN의 초깃값을 다음과 같이 주었다.
MAX = -10e9-1
MIN = 10e9+1
# 순열이 담긴 operation_list에서 하나씩 빼서 해당 경우의 수를 다 계산해준다.
# operation_list는 [('+', '-', '*', '/', '+'), ('+', '-', '/', '*', '+'),...] 이와 같이 나온다.
# 각각 튜플에 N-1개의 연산자가 담겨있기 때문에 이를 다 계산한뒤, 최댓값 최솟값을 리턴한다.
print(operation_list)
for o in operation_list:
answer = A[0]
for i in range(N-1):
if o[i] == '+':
answer += A[i+1]
elif o[i] == '-':
answer -= A[i+1]
elif o[i] == '*':
answer *= A[i+1]
else:
if answer < 0:
answer = -(-answer//A[i+1])
else:
answer //= A[i+1]
if answer < MIN:
MIN = answer
if answer > MAX:
MAX = answer
print(MAX)
print(MIN)
[다른 사람의 풀이]
import sys
from itertools import permutations
from math import inf
# ------------ input ------------
input = sys.stdin.readline
n = int(input())
nums = list(map(int, input().split()))
plus, minus, prod, divide = map(int, input().split())
# ------------ solution ------------
perm = set(permutations([0]*plus + [1]*minus + [2]*prod + [3]*divide, n-1))
M = -inf
m = inf
for oper in perm:
tmp = nums[0]
for i in range(1,n):
if oper[i-1] == 0:
tmp += nums[i]
elif oper[i-1] == 1:
tmp -= nums[i]
elif oper[i-1] == 2:
tmp *= nums[i]
else:
if tmp<0:
tmp = -((-tmp)//nums[i])
else:
tmp//=nums[i]
M = max(M, tmp)
m = min(m, tmp)
print(M)
print(m)
import sys
import itertools
input = sys.stdin.readline
N = int(input())
A = list(map(int, input().split()))
O = list(map(int, input().split()))
o_list =[]
result=[]
for i in range(len(O)):
for _ in range(O[i]):
o_list.append(i)
o_list = set(itertools.permutations(o_list,N-1))
for o in o_list:
temp=A[0]
for idx,val in enumerate(A[1:]):
if o[idx]==0:temp=temp+val
elif o[idx]==1:temp=temp-val
elif o[idx]==2:temp=temp*val
elif o[idx]==3:
if temp<0:temp = -(-temp//val)
else:temp=temp//val
result.append(temp)
print(max(result))
print(min(result))
[느낀점]
- 순열 문제를 처음 풀어봤는데, permutations라는 모듈을 알게 돼서 좋았다.
- 비록 찾아보고 이해하고 다시 풀었지만 이런 문제는 이렇게 접근하면 되겠다는 것을 알게 돼서 뿌듯하다
'알고리즘 > 알고리즘 문제' 카테고리의 다른 글
[python] 백준 > bfs > 스타트 링크 (0) | 2021.01.20 |
---|---|
[python] 프로그래머스 > 올바른 괄호 (0) | 2021.01.20 |
[python] 프로그래머스 > 두 개 뽑아서 더하기 (0) | 2021.01.19 |
[python] 백준 > bfs > 4연산 (0) | 2021.01.19 |
[python] 백준 > 부르트포스 > 덩치 (0) | 2021.01.18 |