Skip to content
CatBus

Tag: backtracking

All the articles with the tag "backtracking".

BOJ14888SILVER 1

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)이 주어진다. 둘째 줄에는 A₁, A₂, …, Aₙ이 주어진다. (1 ≤ Aᵢ ≤ 100) 셋째 줄에는 덧셈, 뺄셈, 곱셈, 나눗셈의 개수가 순서대로 주어진다.

출력

첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다.

이 문제는 백트래킹을 이용한 브루트포스 문제이다. 가능한 모든 연산자 조합을 시도하여 최대값과 최소값을 찾는다.

  1. DFS를 이용하여 모든 연산자 배치 조합을 탐색
  2. 각 단계에서 사용 가능한 연산자를 선택하고 계산
  3. 모든 수를 사용했을 때 결과를 비교하여 최대/최소 갱신
  • 현재 결과값과 사용할 다음 수를 가지고 재귀
  • 각 연산자 종류별로 남은 개수가 있으면 시도
  • 연산 후 다음 단계로 진행
  • 백트래킹: 연산자 개수 복구
operate = ['+', '-', '*','/']

N = int(input())
nums = list(map(int, input().split()))
operator_counter = list(map(int, input().split()))
operator_cnt = sum(operator_counter)

max_com = -float('inf')
min_com = float('inf')


def compute(a, b, op_i):
    if op_i == 0:
        return a + b
    elif op_i == 1:
        return a - b
    elif op_i == 2:
        return a * b
    elif op_i == 3:
        return int(a / b)

def dfs(operator_counter, result, n=0):
    global max_com, min_com
    if n == operator_cnt:
        max_com = max(max_com, result)
        min_com = min(min_com, result)
        return
    for i, cnt in enumerate(operator_counter):
        if cnt == 0:
            continue
        operator_counter[i] -= 1
        dfs(operator_counter, compute(result, nums[n+1], i), n+1)
        operator_counter[i] += 1


dfs(operator_counter, nums[0])

print(max_com)
print(min_com)

연산자 끼워넣기

백준 14888번 '연산자 끼워넣기' (실버 1) 문제 풀이. bruteforcing, backtracking 로 접근했다.

2025.04.16·7분·bruteforcing
BOJ14712GOLD 5
def fill_nemo(d=0):
    global cnt
    if N*M == d:
        cnt += 1
        return
    
    y = d // M + 1
    x = d  % M + 1

    # 사각형이 완성 안되는 경우(넴모를 놓을 수 있는 경우)
    if matrix[y-1][x] == 0 or matrix[y-1][x-1] == 0 or matrix[y][x-1] == 0:
        # 다음 위치에 네모 생성
        matrix[y][x] = 1
        fill_nemo(d+1)
        matrix[y][x] = 0

    # 다음 위치에 네모 생성 X
    fill_nemo(d+1)
    

N, M = map(int, input().split())

matrix = [[0]*(M+1) for _ in range(N+1)]

cnt = 0
fill_nemo()

print(cnt)

넴모넴모 (Easy)

백준 14712번 '넴모넴모 (Easy)' (골드 5) 문제 풀이. bruteforcing, backtracking 로 접근했다.

2024.09.09·4분·bruteforcing
SWEA2112모의역량
test_case = int(input())

def chk_test():
    chk_a_list = [0] * k
    chk_b_list = [1] * k

    for w_i in range(w):
        is_success = False

        for d_i in range(d - k + 1):
            cur_chk = [film[tmp_i][w_i] for tmp_i in range(d_i, d_i + k)]
            if cur_chk == chk_a_list or cur_chk == chk_b_list:
                is_success = True
                break
        if not is_success:
            return False
    return True


def test_film(film, depth=0, cnt_inject=0, chk_list=[]):
    global min_inject
    
    if cnt_inject >= min_inject:
        return

    if chk_test():
        min_inject = min(min_inject, cnt_inject)
        return

    if depth >= d:
        return
    
    origin_membrane = film[depth][:]

    # 현재 층을 그대로
    test_film(film, depth + 1, cnt_inject)

    # 현재 층을 a로
    film[depth] = inject_a
    test_film(film, depth + 1, cnt_inject + 1)
    film[depth] = origin_membrane

    # 현재 층을 b로
    film[depth] = inject_b
    test_film(film, depth + 1, cnt_inject + 1)
    film[depth] = origin_membrane

for t in range(test_case):
    d, w, k = map(int, input().split())

    film = [list(map(int, input().split())) for _ in range(d)]
    
    inject_a = [0] * w
    inject_b = [1] * w

    min_inject = float('inf')

    test_film(film)
    print(f"#{t + 1} {min_inject}")

보호 필름

SWEA 2112번 '보호 필름' (모의 역량 테스트) 문제 풀이. dfs, backtracking 로 접근했다.

2024.08.14·7분·dfs
SWEA4012모의역량
test_case = int(input())

def search_recipe(index_list, n):
    if n == 1 :
        return [[i] for i in index_list]
    result = []
    for i in range(len(index_list) - 1):
        for j in search_recipe(index_list[i+1:], n - 1):
            result.append([index_list[i]] + j)
    
    return result


for t in range(test_case):
    n = int(input())
    min_diff = float('inf')

    recipe = [list(map(int, input().split())) for _ in range(n)]
    
    index_set = set(range(n))

    comb_list = [[0] + c for c in search_recipe(list(range(1, n)), n // 2 - 1)]

    for comb in comb_list:
        comb2 = list(index_set - set(comb))
        food1, food2 = 0, 0

        for i_idx, (i1, i2) in enumerate(zip(comb, comb2)):
            for j1, j2 in zip(comb[i_idx + 1:], comb2[i_idx + 1:]):
                food1 += recipe[i1][j1] + recipe[j1][i1]
                food2 += recipe[i2][j2] + recipe[j2][i2]
        min_diff = min(min_diff, abs(food1 - food2))

    print(f"#{t + 1} {min_diff}")

요리사

SWEA 4012번 '요리사' (모의 역량 테스트) 문제 풀이. combinatorics, backtracking 로 접근했다.

2024.08.06·6분·combinatorics