R
, C
: 맵의 크기 ()
K
: 찾으려는 거리
왼쪽 아래에서 시작해서 오른쪽 위까지 R
×C
크기의 맵을 이동할 수 있는 경우의 수를 구하고, 그 중 거리가 K인 경우의 수의 가짓수를 구하는 문제이다.
DFS를 활용해 시작점에서 끝점까지 이동하는 모든 경우의 수를 구하면서 문제에 따라 종료 조건을 구성해 불필요한 연산을 줄이는 방향으로 구현한다.
최단 거리가 아닌 K
거리를 이동하는 모든 가짓수를 구해야 하므로 BFS보다 DFS를 선택했다.
이동은 상하좌우로 하기에 4가지 방향을 정의한다.
지나친 곳은 다시 방문하지 않으므로 방문한 곳을 저장해야 한다 → 방문 리스트 정의 필요!
DFS 탐색 조건은 다음과 같이 정의한다.
R
×C
범위 내T
가 아닌 경우K
를 초과할 경우K
를 초과하지 않으면서 목적지에 도착했을 경우이동 거리의 최대인 K
는 →
경우의 수는 중복 없이 순서 있는 K개 선택 문제와 동일하므로 순열의 개수가 됨 →
최종 시간복잡도
최악일 때 장애물이 하나도 없어 모든 칸에서 경우의 수를 탐색해야 하므로 이 되는데 이는 충분히 수행 가능하다.
RecursionError: maximum recursion depth exceeded in comparison
발생import sys
from collections import deque
input = sys.stdin.readline
# dfs 정의
def dfs(x, y, current_distance):
global answer
# 종료 조건 1 : 도착점에 도착
if (x, y) == (end_x, end_y):
if current_distance == K:
answer += 1
return # 도착했으니 탐색 종료
# 종료 조건 2 : 거리가 K 넘음
if current_distance > K:
return
# 4방향 탐색
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
# 범위와 맵 정보 확인
if 0 <= nx < R and 0 <= ny < C and not visited[nx][ny] and map_info[nx][ny] != 'T':
visited[nx][ny] = True
dfs(nx, ny, current_distance+1)
visited[nx][ny] = False
# 입력 받기
R, C, K = map(int, input().split())
map_info = [list(input().rstrip()) for _ in range(R)]
# 방문 리스트 정의
visited = [[False] * C for _ in range(R)]
# 정답 변수 초기화
answer = 0
# 이동 방향 정의
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
# 왼쪽 아래부터 오른쪽 위로 이동
start_x, start_y = R - 1, 0
end_x, end_y = 0, C - 1
# 시작점 방문 처리
visited[start_x][start_y] = True
# DFS 수행
dfs(start_x, start_y, 1)
# 정답 출력
print(answer)