알고리즘/문제 풀이

13594번: 숨바꼭질 3

Themion 2022. 1. 10. 16:34

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

 

13549번: 숨바꼭질 3

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

www.acmicpc.net

각 점을 노드로, 수빈이 1초만에 이동 가능한 좌표 간의 관계를 에지로 보면 이 문제는 BFS 문제임을 알 수 있다. 단, 순간이동을 하는 경우 시간 소모가 없으므로 어느 노드를 방문할 때 반드시 해당 노드에서 순간 이동으로 도착할 수 있는 노드를 전부 탐색하여야 한다.

#include <cstdio>
#include <queue>

using namespace std;

#define MAX_N 100000

bool visit[MAX_N]= { 0, };
queue<int> q;

// 노드 N에 도착했을 때 노드 N에서 텔레포트로 이동 가능한 노드를 모두 방문
void push(int N) {
    // 노드 N의 값이 MAX_N을 넘지 않을 동안 계속해서 텔레포트
    for (; N <= MAX_N && !visit[N]; N *= 2) {
        // N을 q에 넣고 visit에 표시
        q.push(N);
        visit[N] = true;
    }
}

int main() {
    // N: 시작 노드, K: 도착 노드, t: 노드 N에서 노드 K까지 이동하는 데에 걸리는 시간
    int N, K, t = 0, len = 1;

    // 시작 노드와 도착 노드를 입력받은 뒤
    scanf("%d %d", &N, &K);
    // N * 2 ^ k를 모두 q에 push
    push(N);

    // 도착 노드가 시작 노드보다 값이 작다면 걸어서 도착 노드로 이동해야 한다
    if (N >= K) t = N - K;
    // 텔레포트를 사용할 수 있다면 bfs를 이용해 탐색
    else while (!q.empty() && !visit[K]) {
        // t초에 탐색 가능한 노드를 모두 탐색했다면 len을 재설정한 뒤 t를 1 늘린다
        if (!--len) {
            len = q.size();
            t++;
        }

        // q에서 노드를 하나 가져온 뒤
        N = q.front();
        q.pop();

        // 1초만에 걸어서 이동 가능한 노드를 모두 push를 통해 방문
        for (auto n : {N - 1, N + 1}) if (n >= 0 && n <= MAX_N) push(n);
    }

    // 노드 K에 도착하는 데 걸리는 최소 시간을 출력
    printf("%d\n", t);

    return 0;
}

'알고리즘 > 문제 풀이' 카테고리의 다른 글

14425번: 문자열 집합  (0) 2022.01.11
14400번: 편의점 2  (0) 2022.01.10
백준 13460번: 구슬 탈출 2  (0) 2022.01.10
13459번: 구슬 탈출  (0) 2022.01.10
13458번: 시험 감독  (0) 2022.01.10