본문 바로가기
코딩테스트/백준

백준 13913] C++ 숨바꼭질4

by Hwan2 2020. 11. 8.
728x90
반응형

해당 문제는 백준 사이트에서 풀 수 있습니다.


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







1. 문제

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 

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

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

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

입력

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

출력

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

예제 입력 1 

5 17

예제 출력 1 

2

힌트

수빈이가 5-10-9-18-17 순으로 가면 2초만에 동생을 찾을 수 있다.

출처



2. 조건

1. 수빈이는 N 위치에서 동생이 있는 K위치까지 가려고 한다.
2. 수빈이는 위치 N에서 +1, -1, *2 하면 1초가 걸린다.
이때 가장 빠른 시간과 경로를 출력해라.

3. 풀이


이 문제 역시 숨바꼭질1, 숨바꼭질2와 비슷한 문제입니다.


단, 가장 빠른 경로를 출력까지 해야 합니다.


처음엔 모든 경로를 vector<int>에 넣으면서 진행했으나, 시간초과가 나오더군요.


그래서 Union 방법과 비슷하게 경로를 배열에 갱신하면서 진행했습니다.


이것 또한 bfs의 장점중 하나인데, 중복되는 길은 넘기면서 현재 갱신된 값이 가장 빠른 값이 됩니다.


이산한 점은 bool isCheck[] 부분을 안쓰고 int visit[]부분만 사용해서 if문으로 했는데 메모리 초과가 나오더군요 ㅡㅡ;;;


이해가 안갔습니다. if (!visit[]) 으로 중복 체크가 가능한데 말이죠 ㅡㅡ;


여튼 배열에 현재 위치를 다음 위치갈 위치로 갱신하면서 진행한 후 K지점에서 역으로 찾아나가면서 문제를 해결했습니다.



4. 코드

#include <iostream>
#include <vector>
#include <queue>

#pragma warning(disable4996)

using namespace std;

int visit[100010];
bool isCheck[100010];

int main() {
    int T;
    int N, M, K;
    int X, Y;
    int answer = 0;

    cin >> N >> K;
    queue<pair<intint>> q;
    q.emplace(N, 0);
    visit[N] = -1;
    isCheck[N] = true;
    
    while (!q.empty()) {
        int locate = q.front().first;
        int cost = q.front().second;
        q.pop();

        if (locate == K) {
            answer = cost;
            break;
        }

        int x_1 = locate - 1;
        int x_2 = locate + 1;
        int x_3 = locate * 2;


        if (0 <= x_1 && !isCheck[x_1]) {
            isCheck[x_1] = true;
            visit[x_1] = locate;
            q.emplace(x_1, cost + 1);
        }

        if (x_2 <= K && !isCheck[x_2]) {
            isCheck[x_2] = true;
            visit[x_2] = locate;
            q.emplace(x_2, cost + 1);
        }

        if (x_3 <= K + 1 && !isCheck[x_3]) {
            isCheck[x_3] = true;
            visit[x_3] = locate;
            q.emplace(x_3, cost + 1);
        }
    }

    cout << answer << endl;
    int idx = K;
    vector<int> v = { K };

    while (visit[idx] != -1) {
        v.emplace_back(visit[idx]);
        idx = visit[idx];
    }

    for (auto itr = v.rbegin(); itr != v.rend(); itr++)
        cout << *itr << " ";
    return 0;
}



반응형

'코딩테스트 > 백준' 카테고리의 다른 글

백준 7569] C++ 토마토(3차원)  (0) 2020.11.10
백준 13913] C++ 벽 부수고 이동하기  (0) 2020.11.09
백준 13549] C++ 숨바꼭질3  (0) 2020.11.07
백준 12851] C++ 숨바꼭질2  (0) 2020.11.06
백준 1697] C++ 숨바꼭질  (0) 2020.11.05

댓글


스킨편집 -> html 편집에서