<문제출처>
https://www.acmicpc.net/problem/1103
<체크포인트>
시간 | 쉽게해결 | 1시간이내 | 1시간 이상 or 몇 일 걸림 | 솔루션 보고 해결 |
체감 난이도 | 하 | 중 | 상 | 최상 |
이해도 | 완벽히이해 | 다소 헷갈리는 부분있음 | 이해못함 | |
덧붙일 말 | dfs탐색 시 조건문 처리를 꼼꼼하게 잘해야한다 |
<고민 끄적끄적>
1, 2번조건을 잘 고려하여 구현만하면 되는 생각보다 간단한 문제였다.
2번의 조건때문에 이 문제를 dp로 분류하는 것 같다. 그래프 탐색 문제풀때는 최소, 최대값등 조건에 안맞으면 탐색하지 않도록해서 시간 복잡도를 줄이는 유형이 많으니 주의해야 한다.(특히 이번 문제처럼 방문값 갱신할 때)
최종코드
import sys; input = sys.stdin.readline
sys.setrecursionlimit(10**7)
def is_ragne(nx, ny):
return 0 <= nx < N and 0 <= ny < M
def dfs(x, y, stack):
dist = int(arr[x][y])
for dx, dy in zip(dxs, dys):
nx, ny = x + (dx*dist), y + (dy*dist)
if is_ragne(nx, ny):
# 구멍에 빠지면 나가기
if arr[nx][ny] == "H":
continue
# 현재 지나온길들중에 다시 방문한다면
if (nx, ny) in stack:
return False
# 첫 방문이라면
if visited[nx][ny] == 0:
visited[nx][ny] = visited[x][y] + 1
stack.append((nx, ny))
if not dfs(nx, ny, stack):
return False
stack.pop()
else:
if visited[x][y] + 1 > visited[nx][ny]:
visited[nx][ny] = visited[x][y] + 1
stack.append((nx, ny))
if not dfs(nx, ny, stack):
return False
stack.pop()
return True
# 변수 선언 및 입력
N, M = map(int, input().split())
arr = [list(input().strip()) for _ in range(N)]
dxs, dys = [-1, 0, 1, 0], [0, 1, 0, -1]
visited = [[0]*M for _ in range(N)] # 최대 이동횟수를 기록
stack = [] # 현재 지나온 길 로그들을 기록
# start
x, y = 0, 0
visited[x][y] = 1
stack.append((x, y))
if not dfs(x, y, stack):
print(-1)
else:
ans = 0
for i in range(N):
for j in range(M):
ans = max(ans, visited[i][j])
print(ans)
그래프 재귀 탐색할 때 최대한 코드가 길거나 복잡해지더라도 else를 자제하고 if문을 꼼꼼하게 처리해서 구현해야지 디버깅 할 때 편한 것 같다.
이 문제에서 나는 현재 지나온 길들을 stack =[] 이라는 리스트 변수에 담아서 in연산자로 확인했다. 하지만 만약 방문한 길들이 엄청나게 길어질 수 있는 경우의 문제라면 in연산자는 시간복잡도를 많이 잡아먹기 때문에(O(n)) 지양해야 한다.
'algorithm > 백준' 카테고리의 다른 글
[백준-파이썬] 10971(Silver)/백트래킹 : 외판원 순회2 (0) | 2023.02.12 |
---|---|
[백준-파이썬] 4811(Gold5)/DP : 알약 (0) | 2023.02.05 |
[백준-파이썬] 14499(Gold4)/구현 : 주사위 굴리기 (0) | 2023.02.05 |
[백준-파이썬] 14942(Platinum5)/dfs : 개미 (0) | 2023.02.05 |
[백준-파이썬] 3109(Gold2)/dfs : 빵집 (0) | 2023.01.28 |