📖 문제 링크
https://www.acmicpc.net/problem/1697
1697번: 숨바꼭질
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
👩💻 문제풀이
처음엔 DP문제라고 생각하고 풀었는데, 가뜩이나 잘 못하는 DP인 데다 정답도 나오지 않았다.
찾아보니 BFS 활용문제.... BFS는 더 못해서 산 넘어 산^^..
각종 블로그를 통해 정답코드를 분석해봐도 너무나도 방대한 양으로 진행되어 파악 불가......
그래서 BFS 기본코드를 디버깅하면서 돌아가는 모습을 확인했다.
# bfs 기본 코드
def bfs(graph, start_node):
visit = list()
queue = list()
queue.append(start_node)
while queue:
node = queue.pop(0)
if node not in visit:
visit.append(node)
queue.extend(graph[node])
return visit
만약 위와 같은 트리로 기본 코드를 돌린다면,
1) 1번 노드가 큐에 들어감 (현재 큐: 1)
2) 큐의 제일 앞에 위치한 노드를 꺼낸다. (현재 큐의 맨 앞 노드는 1이므로 1을 꺼냄)
3) 노드에 연결된 자식 노드들을 큐의 맨뒤에 차례로 붙여준다. (현재 큐 : 2, 3)
4) 큐의 맨앞 노드를 꺼낸다(2번을 그대로 하는 것. 현재 큐의 맨 앞 노드는 2이므로 2를 꺼낸다.)
5) 2번 노드를 꺼냈으므로, 2번 노드에 연결된 자식 노드들을 큐의 맨 뒤에 차례로 붙인다(3번 반복, 현재 큐 : 3, 4, 5, 6 )
6) 2~3번을 반복
이렇게 하면 순회 순서는 (1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9)가 된다.
이렇게 기본 코드의 동작 방식을 익히고 나서 본 문제를 다시 보았다.
처음 출발지(x)부터 x-1, x+1, x*2 의 세 가지 방식으로 나아갈 수 있고,
각각의 방식 또한 -1, +1, *2로 계속 뻗어나간다.
그렇기에 기본 BFS 코드에서 각각의 계산된 경우를 조회하도록 코드를 추가하고,
목적지와 노드가 같아지면 코드를 중단한다. 예제로 보았을 때 특정 노드가 17이 되면 종료한다는 의미이다.
그리고 중요한 점은 파이썬에서 queue가 아닌 deque를 써야 한다는 점!
queue는 시간초과의 원인이 된다.
다음에 이 문제를 다시 풀 땐 어려움 없이 풀 수 있길...
✅ 최종 코드
from collections import deque
n, k = map(int, input().split())
visit = [0] * 1000001
def bfs(n):
queue = deque()
queue.append(n)
while queue:
node = queue.popleft()
if node==k:
print(visit[node])
return
for next in (node-1,node+1,node*2):
if 0<=next<100001 and not visit[next]:
visit[next] = visit[node]+1
queue.append(next)
bfs(n)
'알고리즘 > Python' 카테고리의 다른 글
[백준/Python] 10610번: 30 (0) | 2022.03.06 |
---|---|
[백준/Python] 10451번: 순열 사이클 (0) | 2022.03.05 |
[백준/Python] 1780번: 종이의 개수 (0) | 2022.03.03 |
[백준/Python] 1707번: 이분 그래프 (0) | 2022.03.01 |
[백준/Python] 11724번: 연결 요소의 개수 (0) | 2022.02.11 |