문제 출처 : https://www.acmicpc.net/problem/1189
문제의 형태만 보아도 그래프 탐색의 문제같이 보입니다 ㅎㅎㅎ
문제에서 나타난 예시로 케이스를 살펴보겠습니다.
한수가 이동할 수 있는 케이스 3번입니다. (거리 8)
한수가 이동할 수 있는 케이스 4번입니다. (거리 6)
한수가 이동할 수 있는 케이스 5번입니다. (거리 8)
한수가 이동할 수 있는 케이스 6번입니다. (거리 6)
한수가 이동할 수 있는 케이스 7번입니다. (거리 6)
모든케이스들을 살펴보았습니다. R은 3 C는 4일때 한수가 이동할 수 있는 경로들과 집에 도달할 때까지의 거리들입니다.
이 케이스에서는 K는 6이기 때문에 위에 살펴본 케이스 중 1, 4, 6, 7번의 케이스가 해당되기 때문에 가짓수는 4이므로 정답은 4가 되는 것입니다.
어떻게 구현해볼 수 있을까요?
DFS(깊이 우선 탐색), 백트래킹을 이용하여 방문하지 않고 T가 아닌 부분으로 한수가 이동하도록 하면 됩니다!
여기서 방문처리는 한수가 이동한 거리로 갱신하여 처리를 했습니다.
import sys
input = sys.stdin.readline
# r: 행, c: 열, k: 거리
r, c, k = map(int, input().strip().split())
graph = []
for _ in range(r):
graph.append(list(input().strip()))
# 상, 우, 하, 좌
move = [[-1, 0], [0, 1], [1, 0], [0, -1]]
# 처음 한수의 위치를 1로 설정
graph[r - 1][0] = 1
# 가짓수를 세기 위한 변수
result = 0
# 집은 오른쪽 맨 위임
def dfs(row, col):
global result
# 한수가 집에 도달했을 경우
if row == 0 and col == c - 1:
# k와 한수가 이동한 거리가 동일하다면 가짓수에 넣어줍니다.
if graph[row][col] == k:
result += 1
return
else:
return
for i in move:
nrow = row + i[0]
ncol = col + i[1]
if nrow >= 0 and ncol >= 0 and nrow < r and ncol < c:
if graph[nrow][ncol] == '.':
graph[nrow][ncol] = graph[row][col] + 1
dfs(nrow, ncol)
# 다음의 케이스에서 이용하기 위해서 방문처리를 해제해줍니다.
graph[nrow][ncol] = '.'
dfs(r - 1, 0)
print(result)
평소 백트래킹과 DFS를 적용하여 문제를 풀려고 시도를 여러번 했었는데 재귀를 이해하는데 좀 어려움이 있어 문제에 적용시키기 힘들었습니다. 하지만! 이번 문제를 한방에 통과했다는것에 너무 기분이 좋고 한층 성장했다는 것을 느꼈습니다!
개인적으로 백트래킹을 이용했기 때문에 이 문제의 알고리즘이 순열의 알고리즘과 매우 유사하다고 느꼈습니다. 특히 재귀함수가 실행되기 전에 방문처리하고 재귀함수가 종료된 후 방문처리를 다시 되돌리는 방법! 이게 포인트입니다!
이 방법이 있었기에 한번의 DFS로 모든 경로를 탐색할 수 있었던 것입니다!
이 글을 보시는 분들께 도움이 되었으면 좋겠습니다!