문제
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
내가 푼 풀이
- BFS로 인접한 접점을 탐색해서 걸린 시간을 출력한다.
- 예제로 주어진 X = 5, K = 17 일때 다음과 같다.
- 이미 방문했던 지점이라면 스킵하고, 방문하지 않은 지점이라면 걸린시간을 더해준다.
- 걸린시간을 계산하기위해 dp[] 의 크기를 100,000만큼 선언해준다. ( 이 문제의 최대지점이 100,000 이기때문에)
- BFS 방식으로 인접한 지점 우선으로 탐색하고, 방문하지 않은 지점이라면 dp[방문할지점] = dp[이전 지점] + 1 을 해준다.
- 위에선 지점 5에서 4로갈때 1초가 들고, 지점 4에서 3으로 갈때, dp[3] = dp[4] + 1 이 된다.
- 이미 방문한 지점을 배열로 선언하여 contains 함수를 이용해 방문 했는지 확인하려 했으나, 시간초과가 떴다.
- BFS, DFS 중 어떤방식을 써야하는지는 알지만, 해당 알고리즘을 코드로 구현할때, 시간초과가 걸리지않게 따로 저장하는 방식을 쓰자
import Foundation
var input = readLine()!.split(separator: " ").map{ Int($0)! }
var needVisitedQueue = [input[0]]
var idx = 0
var arr = [Int]()
var dp = Array(repeating: 0, count: 100001)
var visited = Array(repeating: 0, count: 100001)
visited[input[0]] = 1
// 소요시간을 저장할 배열 DP
// 해당 지점을 방문했는지 확인하기위한 배열 visited (visited[n] == 1 이면 지점 N은 이미 방문했다.)
// BFS로 시작점에서 인접한 노드순으로 탐색한다.
while idx < needVisitedQueue.count {
var node = needVisitedQueue[idx]
idx += 1
if node == input[1] { break }
// 해당 노드의 인접노드들이 범위안에 있고, 방문하지 않은곳이라면 다음방문 순서로 둔다.
if node-1 >= 0 && visited[node-1] != 1 {
needVisitedQueue.append(node-1)
visited[node-1] = 1
dp[node-1] = dp[node] + 1
}
if node+1 <= 100000 && visited[node+1] != 1 {
needVisitedQueue.append(node+1)
visited[node+1] = 1
dp[node+1] = dp[node] + 1
}
if node*2 <= 100000 && visited[node*2] != 1 {
needVisitedQueue.append(node*2)
visited[node*2] = 1
dp[node*2] = dp[node] + 1
}
}
print(dp[input[1]])
'코딩테스트 > 백준' 카테고리의 다른 글
BOJ-12904 A와B Swift (0) | 2023.05.31 |
---|---|
BOJ-2225 합분해 Swift (0) | 2023.05.31 |
BOJ-7576 토마토 Swift (0) | 2023.05.30 |
BOJ-15903 카드 합체 놀이 Swift (0) | 2023.05.30 |
BOJ-10775 공항 Swift (1) | 2023.05.30 |