https://www.acmicpc.net/problem/15684
이해
- 사다리를 모두 놓아보면서 판별해야하는 문제
- DFS 를 통해 완전 탐색을 하되, 중간 가지치기를 이용한 시간을 단축해야함
구현
- 사다리 타기를 통해 i → i 가 모두 가능한 지 체크 하는 함수
- DFS를 통해 사다리를 놓는 경로를 모두 탐색해야하는 함수
- 사다리 조작에 있어 사다리를 추가할 때, 추가한 사다리가 3개가 초과되면 가지치기
- 만약 이전에 확인된 사다리의 조작한 사다리 수가 현재 돌고 있는 사다리의 조작한 사다리 수 보다 높은 경우 가지치기
- 사다리를 놓음에 있어 만약 2개 혹은 3개째 사다리를 놓을 때는 이전에 놓았던 사다리 위치보다 위에 놓을 필요가 없음
코드
# 15684 사다리 조작
import sys
input = sys.stdin.readline
def check_ladder() -> bool:
for i in range(N):
y, x = 0, i
while y < H:
if ladders[y][x] == 1: # 1이면 왼쪽으로 이동
x -= 1
elif ladders[y][x] == 2: # 2면 오른쪽으로 이동
x += 1
y += 1
if x != i: # i -> i 가 아닐경우 False
return 0
return 1 # 모두 i -> i 되면 True
# 백트래킹
def bt(cnt:int, start_i:int) -> None:
global ans
if check_ladder(): # i-> i 체크
# 된다면 cnt 저장
ans = min(cnt, ans)
return
if cnt == 3: # 3 이하일 때만 허용
return
if cnt >= ans:
return
# i -> i가 안 될 경우, 탐색 중이었던 높이부터 체크하면 됨
for i in range(start_i, H):
for j in range(N-1):
if not ladders[i][j] and not ladders[i][j+1]:
ladders[i][j] = 2
ladders[i][j+1] = 1
bt(cnt+1, i)
ladders[i][j] = 0
ladders[i][j+1] = 0
return
if __name__ == "__main__":
N, M, H = map(int, input().split())
ladders = [[0] * N for _ in range(H)]
visited = [[0] * N for _ in range(H)]
for _ in range(M):
# 1 -> 왼쪽, 2 -> 오른쪽
a, b = map(int, input().split())
ladders[a-1][b-1] = 2
ladders[a-1][b] = 1
ans = 5
bt(0,0)
print(-1 if ans > 3 else ans)
반응형
'Algorithm > BaekJoon Review' 카테고리의 다른 글
9935. 문자열 폭발 (0) | 2024.01.21 |
---|---|
1149. RGB거리 (0) | 2024.01.15 |
1932. 정수 삼각형 (0) | 2024.01.11 |
18111. 마인크래프트 (1) | 2024.01.09 |
1717. 집합의 표현 (2) | 2024.01.07 |