[BOJ] 숨바꼭질 2 (no.12851)

숑숑·2021년 1월 22일
0

알고리즘

목록 보기
42/122

문제

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 그리고, 가장 빠른 시간으로 찾는 방법이 몇 가지 인지 구하는 프로그램을 작성하시오.

입력

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

출력

첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

둘째 줄에는 가장 빠른 시간으로 수빈이가 동생을 찾는 방법의 수를 출력한다.


🤔 생각

  • 다른 숨바꼭질 문제에서 짰던 코드처럼 하면 모든 경우를 고려하지 않게 된다.

  • 큐잉 할 때마다 바로 방문 처리해주면, 다른 경우가 모두 생략되버린다. (여태까지는 거리만 도출하면 됐으므로 이래도 전혀 상관이 없었다.)

  • 그럼 큐에 넣을 때 말고, pop 할 때 방문처리하면 모든 경우를 고려할 수 있다.

  • 타겟이 있는 레벨의 큐에, 타겟 노드가 몇개 들어있는지만 세어주면 그게 방법의 수가 되겠다.

📌 내 풀이

import sys
input = sys.stdin.readline

def main():

    def bfs(n,k):
        q = [n]
        cache = [False]*100001
        cnt = 0

        while q:
            tmp = []

            for x in q:
                if x == k:
                    print(cnt, q.count(k), sep="\n")
                    return

                cache[x] = True
                for i in (x-1, x+1, x*2):
                    if 0 <= i < 100001 and not cache[i]: tmp.append(i)
            
            q = tmp
            cnt += 1

    n,k = map(int, input().split())
    bfs(n,k)


if __name__ == "__main__":
    sys.exit(main())

🤷‍ 의문점

tmp += [i for i in (x-1, x+1, x*2) if 0 <= i < 100001 and not cache[i]]
  • 위처럼 tmp에 노드 삽입하는 부분을 list comprehension으로 구현해서 제출해봤더니, 약 30ms 정도 더 오래 걸렸다.

  • 반복문으로 append 함수 호출해서 리스트 만드는 것보다 '보통은' 빠르다고 알고 있는데 왜 이 문제에선 더 느린건지 모르겠다...

✔ 회고

  • 솔직히 바로 생각해내진 못했고 직접 그려보고 나서야 눈치챈 방식이다.
  • 최단경로의 경우의 수를 구할 땐 pop할 때 방문처리해야 한다는걸 기억하자.
profile
툴 만들기 좋아하는 삽질 전문(...) 주니어 백엔드 개발자입니다.

0개의 댓글