티스토리 뷰

알고리즘

백준 16953 - 파이썬

취뽀가자!! 2023. 4. 16. 20:29

https://www.acmicpc.net/problem/16953

 

16953번: A → B

첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다.

www.acmicpc.net

 

문제 풀이

처음에 이 문제를 봤을 때 떠오른 아이디어는 bottom up 방식으로 푸는것보다 top down 방식으로 푸는게 훨씬 빠르겠다는 생각이 들었다. 그래서 162 -> 81 -> 8 -> 4 -> 2 이런식으로 해결해 보았다.

 

x, y = map(int, input().split())

result = 1

while y != x:
  temp = y
  result +=1
 
  if y % 10 == 1:
    y //= 10

  elif y % 2 == 0:
    y //= 2

  if temp == y:
    print(-1)
    break

print(result)

그런데 이렇게 해보니 결과는 틀렸다고 나왔다. 왜 그런지 고민해 보다가 해결책을 찾지 못해서 다른 사람의 풀이를 찾아 보았다. 이 분의 풀이에는 temp라는 변수가 나와 다른 점이었는데, 이 변수에 계산되기 이전의 y값을 넣어 맨 마지막에 비교하여 서로 같은 값이 나올 경우 while문을 탈출하지 못 하였다는 것이기 때문에 -1이 출력되도록 하였다. 이 점이 나와 다른 점이었던거 같다.

 

x,y = map(int,input().split())

result = 1

while y != x:
    result+=1
    temp = y
    if y%10 == 1:
        y//=10
    elif y%2 == 0:
        y//=2
    
    if temp == y:
        print(-1)
        break
else:
    print(result)

구글링을 하다가 큐를 사용하여 푼 코드도 찾아보았다.

BFS를 이용한 방식이다.

from collections import deque

a, b = map(int, input().split())

res = -1
que = deque([(a,1)])

while que:
  i, cnt = que.popleft()

  if i == b:
    res = cnt
    break

  if i*2 <= b:
    que.append((i*2, cnt+1))
  if int(str(i) + '1') <= b:
    que.append((int(str(i) + '1'), cnt+1))

print(res)

2 162
deque([(2, 1)])
deque([(4, 2), (21, 2)])
deque([(21, 2), (8, 3), (41, 3)])
deque([(8, 3), (41, 3), (42, 3)])
deque([(41, 3), (42, 3), (16, 4), (81, 4)])
deque([(42, 3), (16, 4), (81, 4), (82, 4)])
deque([(16, 4), (81, 4), (82, 4), (84, 4)])
deque([(81, 4), (82, 4), (84, 4), (32, 5), (161, 5)])
deque([(82, 4), (84, 4), (32, 5), (161, 5), (162, 5)])
deque([(84, 4), (32, 5), (161, 5), (162, 5)])
deque([(32, 5), (161, 5), (162, 5)])
deque([(161, 5), (162, 5), (64, 6)])
deque([(162, 5), (64, 6)])
5

 

deque에 값이 들어가는 것을 출력해보면 위와 같다. 

if i*2 <= b:
    que.append((i*2, cnt+1))
  if int(str(i) + '1') <= b:
    que.append((int(str(i) + '1'), cnt+1))

이 부분이 핵심인데 2를 곱하는 경우와 맨 뒤에 1을 추가하는 경우의 수를 모두 큐에 추가하여 구하는 방식이다.

 

또 다른 방식으로는 heapq를 이용하여 구현한 방식도 있다.

import sys
import heapq

input = sys.stdin.readline

a, b = map(int, input().split())

def mulTwo(a, count):
  return count+1, a*2

def addOne(a, count):
  return count+1, int(str(a) +'1')

def solution(a, b):
  q = [(0, a)]
  while q:
    print(q)
    cnt, a = heapq.heappop(q)
    if a<b:
      heapq.heappush(q, mulTwo(a, cnt))
      heapq.heappush(q, addOne(a, cnt))

    elif a == b:
      return cnt+1
    else:
      continue

  return -1

print(solution(a,b))

heap에 추가되는 순서대로 출력해보면 다음과 같다.

 

[(0, 2)]
[(1, 4), (1, 21)]
[(1, 21), (2, 8), (2, 41)]
[(2, 8), (2, 41), (2, 42), (2, 211)]
[(2, 41), (2, 211), (2, 42), (3, 16), (3, 81)]
[(2, 42), (2, 211), (3, 81), (3, 16), (3, 82), (3, 411)]
[(2, 211), (3, 16), (3, 81), (3, 411), (3, 82), (3, 84), (3, 421)]
[(3, 16), (3, 82), (3, 81), (3, 411), (3, 421), (3, 84)]
[(3, 81), (3, 82), (3, 84), (3, 411), (3, 421), (4, 32), (4, 161)]
[(3, 82), (3, 411), (3, 84), (4, 161), (3, 421), (4, 32), (4, 162), (4, 811)]
[(3, 84), (3, 411), (4, 32), (4, 161), (3, 421), (4, 811), (4, 162), (4, 164), (4, 821)]
[(3, 411), (3, 421), (4, 32), (4, 161), (4, 821), (4, 811), (4, 162), (4, 164), (4, 168), (4, 841)]
[(3, 421), (4, 161), (4, 32), (4, 164), (4, 821), (4, 811), (4, 162), (4, 841), (4, 168)]
[(4, 32), (4, 161), (4, 162), (4, 164), (4, 821), (4, 811), (4, 168), (4, 841)]
[(4, 161), (4, 164), (4, 162), (4, 841), (4, 821), (4, 811), (4, 168), (5, 64), (5, 321)]
[(4, 162), (4, 164), (4, 168), (4, 841), (4, 821), (4, 811), (5, 321), (5, 64), (5, 322), (5, 1611)]

 

이처럼 계속 맨 왼쪽에 있는 값을 꺼내어 확인 후 b의 값과 일치하면 해당 힙에 같이 저장되어 있던 카운트를 출력해주는 원리이다.

 

이 문제를 풀면서 느낀 점은 맨 첨에 top dwon 방식으로 풀면서 정답을 거의 가까이 유추하였지만 반복문 탈출하는 방식을 생각하지 못한 점이 아쉽다. 또한 한 가지 답을 구하는데 있어 정말 여러가지 풀이 방식이 존재한다는 것이다. 따라서 풀었다고 다음 문제로 넘어가는 것이 아닌 다른 풀이는 없는지 찾아보면서 견식을 확장하는것이 중요한거 같다.

'알고리즘' 카테고리의 다른 글

백준 1339 - 파이썬  (0) 2023.04.19
백준 1439 - 파이썬  (0) 2023.04.17
백준 1946 - 파이썬  (0) 2023.04.16
백준 13305 - 파이썬  (0) 2023.03.05
백준 2217 - 파이썬  (0) 2023.03.01
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함