[PS] BOJ 16953 / A → B
문제 링크: https://www.acmicpc.net/problem/16953
Thumbnail: Photo by Suhyeon Choi (Unsplash)
놀랍게도 그래프 탐색으로 풀 수 있습니다.
풀이
처음 봤을때는 어떻게 풀어야 하는지 고민했는데, 태그에 그래프 탐색을 보자마자 방법이 떠올랐습니다.
엥? 이게 그래프 탐색이라고?
BFS(Breadth-First Search, 너비 우선 탐색)을 생각해봅시다. 큐를 기반으로, 현재 노드의 처리 과정에서 다음에 방문할 노드를 큐에 넣고, 다시 큐에서 하나 하나 꺼내가며 탐색합니다. 그렇다면, 굳이 방문할 다음 노드가 꼭 일반적인 그래프의 형태가 아니어도 되지 않을까요?
이 문제에서는 다음 노드 대신에 다음에 계산할 수를 넣어서 너비 우선 탐색을 진행할 수 있습니다. 다음에 계산해야 하는 수는 아래 2가지입니다.
- 2를 곱한다.
- 1을 수의 가장 오른쪽에 추가한다.
- 어떤 수 \(X\)에 대해, \(X \times 10 + 1\)과 같습니다.
반복문의 종료 조건은 아래와 같이 설정할 수 있습니다.
- queue가 남아 있을 동안 반복하면서...
- 아래의 경우에 종료
- 만약 현재 탐색중인 수가 \(B\)와 같다면
- 이 때는 연산 횟수를 출력합니다.
- 다음 탐색 후보가 전부 \(B\)보다 크다면
- 이 때는 -1을 출력합니다.
- 만약 현재 탐색중인 수가 \(B\)와 같다면
전체 코드
from collections import deque
input = open(0).readline
A, B = map(int, input().split())
queue = deque(((A, 1),))
while queue:
x, count = queue.popleft()
if x == B:
print(count)
break
if x * 2 <= B:
queue.append((x * 2, count + 1))
if x * 10 + 1 <= B:
queue.append((x * 10 + 1, count + 1))
count += 1
else:
print(-1)solution.py
시행착오
연산 횟수를 원래 단일 전역 변수로 기록했는데, 막상 이렇게 하니 서로 다른 경우를 탐색하면서 무분별하게 수가 올라가 정답보다 아득히 많은 숫자가 나왔습니다.
그래서, 큐에 다음 탐색할 수를 추가할 때 동시에 해당 숫자 까지의 연산 횟수를 함께 기록해서 해결했습니다.