본문 바로가기

알고리즘/알고리즘 문제

[python] 백준 > 연산자 끼워넣기

[문제]

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라는 모듈을 알게 돼서 좋았다.
  • 비록 찾아보고 이해하고 다시 풀었지만 이런 문제는 이렇게 접근하면 되겠다는 것을 알게 돼서 뿌듯하다