[백준/Python(파이썬)] 14888

2025. 2. 13.·백준

https://www.acmicpc.net/problem/14888

연산자 끼워넣기(삼성 SW 역량 테스트 기출 문제 1) - 실버 1

💫 알고리즘

백트래킹

후보 해를 한 단계씩 구축하며, 조건에 맞지 않는 경우 이전 단계로 되돌아가 다른 선택지를 탐색

깊이 우선 탐색(DFS)과 유사하며, 유망하지 않은 경로를 조기에 배제하여 탐색 효율을 높임

퍼즐, 조합 최적화, N-Queen 문제 등 복잡한 문제에서 가능한 해의 공간을 체계적으로 탐색


💡 풀이방향

🐢 백트래킹을 사용하여 연산자들을 모든 가능한 순서로 조합하여 최댓값과 최솟값을 찾는 문제

1️⃣ 수(A)의 순서는 변경할 수 없음

2️⃣ 연산자 우선순위를 무시하고 왼쪽에서 오른쪽으로 차례대로 연산

3️⃣ 나눗셈은 C++14 기준: 음수를 양수로 나눈 후 몫을 취하고, 그 몫을 다시 음수로 변환

4️⃣ 연산자의 모든 경우의 수 탐색을 위해 백트래킹(DFS) 사용

5️⃣ 모든 가능한 연산 순서를 탐색

: 각 연산자의 경우를 따로 탐색해야 하므로 여러 개의 if문을 둔 후 재귀적 탐색

6️⃣ 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력만 주어짐


🌟 코드 구현 + 👀 풀이

[전체 코드]

import sys
input = sys.stdin.readline

N = int(input())
A = list(map(int, input().split()))
op = list(map(int, input().split()))

max_val = -1e9
min_val = 1e9

def dfs(index, result, add, sub, mul, div):
    global max_val, min_val

    if index == N:
        max_val = max(max_val, result)
        min_val = min(min_val, result)
        return

    if add:
        dfs(index + 1, result + A[index], add - 1, sub, mul, div)
    if sub:    
        dfs(index + 1, result - A[index], add, sub - 1, mul, div)
    if mul:
        dfs(index + 1, result * A[index], add, sub, mul - 1, div)
    if div:
        dfs(index + 1, int(result / A[index]), add, sub, mul, div - 1)

dfs(1, A[0], op[0], op[1], op[2], op[3])

print(int(max_val))
print(int(min_val))

 

op = list(map(int, input().split()))

op에는 연산자 개수 리스트 저장([+, -, *, /] 개수)

 

max_val = -1e9

min_val = 1e9

조건에 따라; 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력값

최댓값, 최솟값 초기화

 

백트래킹(DFS): def dfs(index, result, add, sub, mul, div):

if index == N:
    max_val = max(max_val, result)
    min_val = min(min_val, result)
    return

모든 숫자를 사용한 경우(index == N) 최댓값과 최솟값을 갱신 후 종료

max_val과 min_val을 최종적으로 가장 큰 값, 작은 값으로 갱신

 

# dfs함수 내 여러 개의 if문
    if add:
        dfs(index + 1, result + A[index], add - 1, sub, mul, div)
    if sub:    
        dfs(index + 1, result - A[index], add, sub - 1, mul, div)
    if mul:
        dfs(index + 1, result * A[index], add, sub, mul - 1, div)
    if div:
        dfs(index + 1, int(result / A[index]), add, sub, mul, div - 1)

🤔 왜 if-elif가 아니라 여러 개의 if문을 쓰나요?

🐢 예시를 들어 설명해 볼게요!

 위의 입력값에서 나올 수 있는 경우는

1️⃣ 3 + 4 = 7, 7 * 5 = 35

2️⃣ 3 * 4 = 12, 12 + 5 = 17

두 가지 경우입니다.

 dfs 첫 호출에서 A1과 A2에 대한 모든 가능한 연산을 확인하려면 if-elif가 아니라 개별적으로 if문을 써야 모든 경우를 탐색할 수 있어요. 첫 호출에서 각 연산자별로 루트가 분기되고, 각 루트에서 또 분기되며 index가 N과 같아졌을 때 값을 max_val, min_val과 비교하며 최댓값, 최솟값을 갱신하는 식이죠! 또 중요한 점은 연산자를 사용했으면 -1을 해줘야 한다는 점인데요, -1을 안 해주면 사용할 연산자가 없는데도 재귀가 실행될 수 있기 때문이에요.

 

🤔 if div: 에서 왜 result // A[index]가 아니라 int(result / A[index])을 하나요?

🐢 음수를 양수로 나눌 때는 C++14의 기준을 따른다는 문제의 조건 때문이에요.

파이썬의 경우 // 을 할 경우 결괏값이 항상 작은 정수 방향으로 내림 처리되는데요.

print(-5 // 2)을 하면 -2가 아닌 -3이 출력돼요. C++14는 -5 // 2의 경우 -2기 때문에

이에 맞춰 int(result / A[index])로 소수점을 버려버리는 거예요!

 

dfs(1, A[0], op[0], op[1], op[2], op[3])

초기 값 설정: A[0]에서 시작 / 연산자 개수를 dfs에 전달 

 

print(int(max_val))

print(int(min_val))

🤔 이건 int함수를 왜 쓰나요? 그대로 max_val, min_val을 출력하면 되는 거 아닌가요?

🐢 처음에 max_val = -1e9, min_val = 1e9로 초기화했었죠? 만약 이 값이 갱신이 안 되면 1e9, -1e9 모두 실수이기 때문에 1000000000.0과 같이 소수점이 포함된 형태로 출력돼요. 이를 피하기 위해 int 함수를 사용해 정수 형태로 바꿔주는 거예요!!

저작자표시 비영리 변경금지 (새창열림)

'백준' 카테고리의 다른 글

[백준/파이썬] 16139  (0) 2025.02.15
[백준/파이썬] 14889  (1) 2025.02.14
[백준/Python(파이썬)] 2580  (0) 2025.02.12
[백준/Python(파이썬)] 9663  (0) 2025.02.11
[백준/Python(파이썬)] 2565  (0) 2025.02.10
'백준' 카테고리의 다른 글
  • [백준/파이썬] 16139
  • [백준/파이썬] 14889
  • [백준/Python(파이썬)] 2580
  • [백준/Python(파이썬)] 9663
우는거북이
우는거북이
  • 우는거북이
    거북이는 울고 있다
    우는거북이
  • 전체
    오늘
    어제
    • 알아보기 (77) N
      • AI (4)
      • 언어 (16)
        • Python (15)
        • C언어 (1)
      • 알고리즘 (7)
      • 백준 (22)
      • 자료구조 (10)
      • 컴퓨터네트워크 (6)
      • 운영체제 (1)
      • 데이터통신 (11) N
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
우는거북이
[백준/Python(파이썬)] 14888
상단으로

티스토리툴바