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

Journey log·2022년 1월 29일
0

🔍문제 링크 : https://www.acmicpc.net/problem/14888

입력 조건
- 첫째 줄에 수의 개수 (2<=n<=11)
- 둘째 줄에 n개의 수가 주어짐.
- 셋째 줄에 합이 n-1인 4개의 정수 주어짐. (+개수, -개수, *개수, /개수)

출력 조건
- n개 수 사이에 부호를 조합하여 연산한 최대값과 최소값 구하기
- 연산자 우선순위를 무시하고 앞에서부터 연산
- 음수를 양수로 나눌 때는 C++14 기준 사용(즉, 양수로 바꾼 뒤 몫을 취하고 그 몫을 음수로 변환)
- 최댓값과 최소값은 (-1e9, 1e9) 범위에 존재. 입력값과 중간연산값도 모두 이 범위 내에 존재.

풀이 과정

  • 1차 : 중복이 되는 경우는 제외해야 하지만(중복 순열 이용해야하지만) 순열로 계산했을 때와 결과 동일할 것. 그래서 순열로 operator_list 찾음. 그런데 시간 초과 뜸
n = int(input())
numbers = list(map(int, input().split()))
operators_count = list(map(int, input().split()))
operators = ["+", "-", "*", "/"]
operators_list = []


def calculate(num_list, oper_list):
    result = num_list[0]
    for i in range(1, len(num_list)):
        if oper_list[i - 1] == "/":
            result = int(result / num_list[i])
        elif oper_list[i - 1] == "+":
            result += num_list[i]
        elif oper_list[i - 1] == "-":
            result -= num_list[i]
        else:
            result *= num_list[i]
    return result


for i, oper in enumerate(operators):
    operators_list += list(operators[i] * operators_count[i])

initial_result = calculate(numbers, operators_list)
min_answer, max_answer = initial_result, initial_result

import itertools

for permutation_result in itertools.permutations(operators_list, len(operators_list)):
    result = calculate(numbers, permutation_result)
    if result < min_answer:
        min_answer = result
    if result > max_answer:
        max_answer = result

print(max_answer)
print(min_answer)
  • 2차: operator는 [+,-,*,/] 중 하나. 그래서 bfs으로 푼다면 bfs((now_index+1)%4), bfs((now_index+2)%4), bfs((now_index+3)%4), bfs((now_index+4)%4)를 만들어서 탐색하는 방법을 생각. 그런데 단계마다 연산 값을 어떻게 저장해야할지 막힘.

  • 솔루션 참고 : 종료조건이 있는 dfs로 풀었다. 함수 인자로 단계, 단계마다 연산 결과를 전달하여 종료 시점에서 min value, max value를 갱신함.

n = int(input())
numbers = list(map(int, input().split()))
plus, minus, mul, div = list(map(int, input().split()))

min_value, max_value = 1e9, -1e9


def dfs(i, now):
    """
    Args:
        i: 현재 연산하는 숫자의 index (i==n 이면 min_valud, max_value 업데이트)
        now : 이전 단계까지 연산한 결과
    """
    global min_value, max_value, plus, minus, mul, div
    if i == n:
        min_value = min(now, min_value)
        max_value = max(now, max_value)
        return
    if plus > 0:
        plus -= 1  # global 변수
        dfs(i + 1, now + numbers[i])
        plus += 1
    if minus > 0:
        minus -= 1
        dfs(i + 1, now - numbers[i])
        minus += 1
    if mul > 0:
        mul -= 1
        dfs(i + 1, now * numbers[i])
        mul += 1
    if div > 0:
        div -= 1
        dfs(i + 1, int(now / numbers[i]))
        div += 1


dfs(1, numbers[0])
print(max_value)
print(min_value)
  • 조합, 순열을 dfs/bfs로 푸는 방식. 16-연구소 문제랑 비슷한 듯
  • a//b == int(a/b) 인줄 알았는데, a가 음수일 경우 결과가 다를 수 있음.
  • plus -= 1; dfs(...); plus += 1 경우의 수 세기. 그리고 plus는 global 변수 처리
profile
DEEP DIVER

0개의 댓글

관련 채용 정보