PS/BOJ

[BOJ/13913/Golang] 백준 13913 - 숨바꼭질 4

wookiist 2021. 6. 2. 21:24
728x90

접근 방식

오랜만에 풀어본 BFS 문제입니다. 일반 숨바꼭질 문제와 똑같습니다만 추가로 이동 방법까지 출력해야 하는 문제입니다. 이동 방법을 구하는 문제라면 이전에도 살펴보았듯이 이전 부모의 이력을 계속 기록해놓았다가 마지막에 역순으로 출력하는 식으로 해결할 수 있습니다.

이 문제에서는 visited 를 확인하는 배열을 따로 두지 않았습니다. 이유는 부모 이력을 기록하는 배열에 이력이 기록된 상태라면 이미 방문한 노드임을 확신할 수 있기 때문입니다.

BFS를 수행하는 과정은 쉬운 BFS 문제들과 거의 유사하기 때문에 코드를 보면서 이해하시는 편이 빠를 것이라 생각합니다.

개선 사항

func printRoute(S int) {
    if P[S] == -1 {
        fmt.Fprintf(w, "%d ", S)
        return
    }
    printRoute(P[S])
    fmt.Fprintf(w, "%d ", S)
}

이력을 출력해주는 함수를 만들었습니다만, 이 함수는 개선할 수 있습니다. 종료 조건을 P[S] == -1 이 아니라, S == N 으로 두면 됩니다. 그러면, 다음과 같이 개선할 수 있습니다.

func printRoute(S) {
    if S != N {
        printRoute(P[S])
    }
    fmt.Fprintf(w, "%d ", S)
}

코드

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

var (
    w  = bufio.NewWriter(os.Stdout)
    sc = bufio.NewScanner(os.Stdin)
)

var (
    P [100001]int
    D [100001]int
)

func init() {
    sc.Split(bufio.ScanWords)
}

func main() {
    defer w.Flush()
    N, K := scanInt(), scanInt()
    for i := range P {
        P[i] = -2
    }
    q := make([]int, 0)
    q = append(q, N)
    P[N] = -1
    D[N] = 0
    for len(q) != 0 {
        nx := q[0]
        q = q[1:]
        if 0 <= nx-1 {
            if P[nx-1] == -2 {
                q = append(q, nx-1)
                D[nx-1] = D[nx] + 1
                P[nx-1] = nx
            }
        }
        if nx+1 <= 100000 {
            if P[nx+1] == -2 {
                q = append(q, nx+1)
                D[nx+1] = D[nx] + 1
                P[nx+1] = nx
            }
        }
        if 2*nx <= 100000 {
            if P[2*nx] == -2 {
                q = append(q, 2*nx)
                D[2*nx] = D[nx] + 1
                P[2*nx] = nx
            }
        }
        if P[K] != -2 {
            break
        }
    }
    fmt.Fprintln(w, D[K])
    printRoute(K)
}

func printRoute(S int) {
    if P[S] == -1 {
        fmt.Fprintf(w, "%d ", S)
        return
    }
    printRoute(P[S])
    fmt.Fprintf(w, "%d ", S)
}

func scanInt() int {
    sc.Scan()
    n, _ := strconv.Atoi(sc.Text())
    return n
}

마무리

여기까지 따라오시느라 고생 많으셨습니다. 만약 이 글이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.

혹시라도 글에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊

728x90
반응형