Search
moon
sun
✅

연산자 끼워넣기

소스코드

import sys input = sys.stdin.readline N = int(input().strip()) A = list(map(int, input().strip().split())) counts = list(map(int, input().strip().split())) # 덧셈, 뺄셈, 곱셈, 나눗셈 개수 max_result = -(float('inf')) min_result = float('inf') def dfs(depth, acc, plus, minus, multiply, divide): global max_result global min_result if depth == N: max_result = max(max_result, acc) min_result = min(min_result, acc) return if plus > 0: dfs(depth + 1, acc + A[depth], plus - 1, minus, multiply, divide) if minus > 0: dfs(depth + 1, acc - A[depth], plus, minus - 1, multiply, divide) if multiply > 0: dfs(depth + 1, acc * A[depth], plus, minus, multiply - 1, divide) if divide > 0: if acc >= 0: dfs(depth + 1, acc // A[depth], plus, minus, multiply, divide - 1) else: dfs(depth + 1, -(-acc // A[depth]), plus, minus, multiply, divide - 1) dfs(1, A[0], counts[0], counts[1], counts[2], counts[3]) print(max_result) print(min_result)
Python
복사

풀이

•
N의 수가 매우 작습니다. 피연산자와 연산자 개수가 N, N-1이라서 트리 문제인가?를 떠올렸습니다. 그 가운데 재귀함수가 생각나서 DFS 함수를 구현했습니다.
◦
재귀함수를 작성하려니 브루트포스 문제처럼 풀어야겠더라구요. 가능한 모든 경우들을 재귀함수를 이용해서 작성했습니다.
▪
AI에게 물어보니, 최대 10개의 연산자 개수가 있는데 단순히 10팩토리얼로 생각해봐도 360만 횟수 정도의 연산횟수라서 문제가 없고 중복이 있는 연산자들에 대해서는 경우의 수가 더 적어지므로 문제가 없다고 했습니다.
◦
재귀함수의 인자 중 연산자들 개수 인자말고는 2개의 인자를 이용했습니다
▪
depth : 종료 조건을 위한 인자입니다. 재귀 호출할 때마다 1씩 증가하며 N에 도달하면 비교 연산을 수행하고 리턴합니다.
▪
acc : 해당 연산자에 대해 값을 누적해 다음 함수에게 전달합니다. 이를 이용해서 depth가 N에 도달한 함수에서 acc로 비교 연산합니다.
•
이미 초기값으로 A[0]을 사용하니 depth를 1로 시작하고 N에 도달하면 종료합니다.
•
함수를 실행하고 max_result, min_result를 출력하면 끝!

회고

•
브루트포스를 쓰려고 하면 본능적으로 거부감이 듭니다. 아마 경우의 수가 많이 커지는 게 본능적으로 회피하게 되는 것 같습니다. 그러나 항상 주어진 값의 크기를 보고 판단해야하는데, 자꾸 직관에 제 문제풀이 방식을 의존하는 경향이 강하다는 생각이 듭니다. 이것 또한 여러 문제를 풀면서 브루트포스인 경우의 허용 크기에 대해 감을 잡아가야할 것 같습니다.
◦
특강에서 배운 재귀에서의 ‘마법의 요정’이 생각보다 제게 도움이 많이 되고 있습니다. 정말 좋네요. 마법의 요정!