문제
https://www.acmicpc.net/problem/14620
14620번: 꽃길
2017년 4월 5일 식목일을 맞이한 진아는 나무를 심는 대신 하이테크관 앞 화단에 꽃을 심어 등교할 때 마다 꽃길을 걷고 싶었다. 진아가 가진 꽃의 씨앗은 꽃을 심고나면 정확히 1년후에 꽃이 피므
www.acmicpc.net
문제 요약
N × N 꽃 밭에 격자 모양의 꽃 3개를 심어야 한다.
꽃은 꽃술 1개와 꽃잎 2개로 이루어져 있다.
화단 밖으로 꽃잎이 나가거나, 서로 다른 꽃잎들이 닿게 될 경우, 꽃은 죽는다.
각 칸은 대여비가 존재하고, 하나의 꽃을 심을 때 5칸의 화단이 필요하다.
세 꽃을 심기 위한 최소 비용을 출력한다.
코드
# 화단 좌표 (x, y)에 꽃을 심을 수 있는지 파악하는 함수
def Isplant(x, y):
if check[x][y]:
return False
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if check[nx][ny]:
return False
return True
# 화단 좌표 (x, y)에 꽃을 심는 함수
def plant(x, y):
global cost
cost += arr[x][y]
check[x][y] = 1
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
check[nx][ny] = 1
cost += arr[nx][ny]
#print(add)
# 화단 좌표 (x, y)의 꽃을 제거하는 함수
def unplant(x, y):
global cost
cost -= arr[x][y]
check[x][y] = 0
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
check[nx][ny] = 0
cost -= arr[nx][ny]
# 백 트래킹으로 어느 곳에 세 꽃을 심어야 가장 비용이 저렴한지 확인하는 함수
def find(cnt):
global res
if cnt == 3: # 심은 개수가 3개라면
if cost < res:
res = cost
#print(f"res는 {cost}로 갱신되었습니다.")
return
for i in range(1, N - 1):
for j in range(1, N - 1):
if Isplant(i, j):
#print(f"심어볼 곳은 {(i, j)}입니다.")
plant(i, j)
find(cnt + 1)
#print(f"지워질 곳은 {(i, j)}입니다.")
unplant(i, j)
N = int(input())
# 화단 한 변의 길이
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
arr = [list(map(int, input().split())) for _ in range(N)]
# arr는 화단의 대여 비용을 저장한 배열
check = [[0] * N for _ in range(N)]
# 화단에 꽃이 있는지를 체크하는 배열
res = 200 * 15
# 가장 저렴한 비용
cost = 0
# 현재 탐색 중인 좌표에 꽃을 심었을 때 드는 비용
find(0)
print(res)
코드 설명
백 트래킹을 이용하여 화단에 꽃을 심을 수 있는 모든 경우의 수를 찾고 가장 싸게 세 꽃을 심을 수 있는 비용을 출력한다.
+ 꽃잎이 화단 밖으로 나가면 안되므로 행과 열을 인덱스 1씩 줄여 탐색한다.
'Algorithm Problems > 완전 탐색' 카테고리의 다른 글
[백준/Python] 2503번: 숫자 야구 (3) | 2023.09.07 |
---|---|
[백준/Python] 10971번: 외판원 순회 2 (3) | 2023.09.01 |
[백준/python] 15684번: 사다리 조작 (2) | 2023.08.09 |
[백준/python] 15663번: N과 M (9) (2) | 2023.08.08 |
[백준/python] 1107번: 리모컨 (2) | 2023.08.07 |