PS(Problem Solving)/BOJ

[백준/BOJ] 12851번: 숨바꼭질 3

JunsuKim 2022. 6. 24.
728x90

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

 

13549번: 숨바꼭질 3

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

문제

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

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

입력

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

출력

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

해설

수빈이가 앞뒤로 1칸씩 움직이는데에 1초, 2배의 위치로 이동하는데에는 0초가 걸린다.bfs를 이용하여 풀려했는데, 0초 걸리는 순간이동이 있어 Queue를 사용할 수 없었다.

 

이를 해결하기 위해 우선순위큐를 사용하였는데, 시간순으로 정렬되어 큐에 들어가게 하면 된다.나머지는 bfs와 다를 것 없이 해결하면 된다.

소스 코드

import java.util.*

private lateinit var visited: BooleanArray
private var ans = 0

data class Info (val time: Int, val idx: Int): Comparable<Info> {
    override fun compareTo(other: Info): Int = time - other.time
}

fun main() = with(System.`in`.bufferedReader()) {
    val (subinIdx, brotherIdx) = readLine().split(" ").map { it.toInt() }
    visited = BooleanArray(100001)

    subinMove(subinIdx, brotherIdx)
    println(ans)
}

private fun subinMove(subinIdx: Int, brotherIdx: Int) {
    val que = PriorityQueue<Info>()
    que.add(Info(0, subinIdx))
    visited[subinIdx] = true

    while(!que.isEmpty()) {
        val time = que.peek().time
        val idx = que.peek().idx
        visited[idx] = true
        que.poll()

        if(idx == brotherIdx) {
            ans = time
            return
        }

        if(idx * 2 in 0..100000 && !visited[idx * 2]) que.add(Info(time, idx * 2))
        if(idx + 1 in 0..100000 && !visited[idx + 1]) que.add(Info(time + 1, idx + 1))
        if(idx - 1 in 0..100000 && !visited[idx - 1]) que.add(Info(time + 1, idx - 1))
    }
}
728x90

댓글