@@@ 알고리즘/백준 스터디

1697 - 해답

HTG 2021. 8. 4. 02:08
728x90

숨바꼭질 

 

문제

수빈이는 동생과 숨바꼭질을 하고 있다. 

수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 

수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 

순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

 

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 

작성하시오.

 

입력

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

 

출력

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


재귀로 풀려고하니깐 아무래도 무한 루프에 빠지게된다.

import sys

N, K = map(int,sys.stdin.readline().split())

def sol(K,cnt):
    print(N)
    if N == K:
        return cnt
    cnt += 1
    if cnt >= max_cnt:
        return max_cnt

    if K % 2:
        return min(sol(K+1,cnt),sol(K-1,cnt))
    else:
        return min(sol(K+1,cnt),sol(K-1,cnt),sol(K//2,cnt))

max_cnt = abs(K-N)
print(sol(K,0))

 

그래서 알고리즘을 보고 BFS로 풀려고 해보았다.

BFS를 하면서 한번 마다 cnt를 증가 시키고 그 수들을 리스트에 넣어서 해보려고 하였지만 시간 초과 발생.

import sys
from collections import deque

N, K = map(int,sys.stdin.readline().split())

visit = [0] * ((K * 2) + 1)

def bfs():
    cnt = 0
    while q:
        ts = q.popleft()
        re_list = []
        cnt += 1
        for t in ts:
            
            visit[t] = 1               
            
            if K in [t-1,t+1,t*2]:
                return cnt
            if t - 1 > 0 and not visit[t]:
                re_list += [t-1]
                visit[t-1] = 1
            if t + 1 < 2*K and not visit[t]:
                re_list += [t+1]
                visit[t+1] = 1
            if t * 2 < 2*K and not visit[t]:
                re_list += [t*2]
                visit[t*2] = 1


        q.append(re_list)
        

if N >= K:
    print(N - K)
else:
    q = deque()
    q.append([N])
    print(bfs())

그래서 찾은 것이 time을 써서 하는 방법

 

import sys
from collections import deque 

def bfs(): 
    q = deque() 
    q.append(N) 
    while q: 
        v = q.popleft() 
        # K에 도착하면 출력
        if v == K: 
            print(time[v]) 
            return 
        # 3 갈래 다 확인
        for next_step in (v-1, v+1, v*2): 
            # 각각이 범위 내에 있고 타임이 0(처음 방문)이라면
            if 0 <= next_step < MAX and not time[next_step]: 
                # 그렇다면 시간이 1증가 시킨다.
                time[next_step] = time[v] + 1 
                q.append(next_step) 
                

N, K = map(int,sys.stdin.readline().split())
# 최대 K의 2배 보다 작을 것이다 곱하기 2이기 때문에
MAX = 2*K
time = [0]*MAX 

# - + * 뿐이기 때문에
# 작은 쪽으로 가는 방법은 - 뿐이다.
if N >= K:
    print(N - K)
else:
    bfs()

 

'@@@ 알고리즘 > 백준 스터디' 카테고리의 다른 글

20206 - 해결  (0) 2021.08.05
1916 - 해답  (0) 2021.08.05
10844 - 해결  (0) 2021.08.03
14713 - 해결  (0) 2021.08.02
18222 - 메모리 초과 - 해답  (0) 2021.08.01