[C++] 백준(BOJ) - 17071 : 숨바꼭질 5

인프런에 있는 큰돌님의 강의 10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트를 듣고 정리한 필기입니다.

문제

백준(BOJ) - 17071 : 숨바꼭질 5(링크)

알고리즘

  1. 완전탐색
  2. BFS
  3. Flood Fill 알고리즘

풀이

  1. 도착점도 동시에 이동하는 BFS 문제
  2. 수빈이의 이동 경우의 수는 총 3가지
    • 현재 위치 x 기준 / x-1, x+1, x * 2
  3. 수빈이가 특정 위치 x에 가장 빠르게 도달한 시간이 t라면 t+2, t+4, t+6, … 초 후에도 x에 도달할 수 있다.
  4. 수빈이가 특정 위치 x에 가장 빠르게 도달할 시간을 홀수, 짝수인 경우로 나누어서 생각한다
    • 도달할 시간이 홀수 짝수가 맞지 않으면 만날 수 없다.
  5. 동생이 홀수 초에 x지점에 도달을 했고, 수빈이가 이전에 홀수 초에 이미 x지점을 방문했다는 것은 동생이 도착한 시점에 다시 x지점에 수빈이가 도착할 수 있다
    • 수빈이의 방문처리 배열 값이 이미 true 인 경우가 무조건 turn의 최소 값

코드

// BOJ-17017 : 숨바꼭질 5
#include <bits/stdc++.h>
using namespace std;

const int MAX = 500000; // 50만 * 50만 배열 공간복잡도 너무 크다
int n, k, turn = 1; 
bool ok;
int visited[2][MAX+4]; // 수빈이의 이동 배열 
                       // 홀수, 짝수 시간대의 이동만 체크

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> k;

    if (n == k) {
        cout << 0 << '\n';
        return 0;
    }

    queue<int> q;
    visited[0][n] = 1;
    q.push(n);

    while (q.size())
    {
        k += turn;
        if (k > MAX) break; // 50만 범위 제한
        
        // 2. 수빈이 먼저 도착하고 수빈 도착과 동생 도착의 홀짝이 맞는 경우
        if (visited[turn % 2][k]) 
        {
            ok = true;
            break;
        }

        // 1. 수빈이가 가면서 동생을 만나는 경우
        // Flood Fill 알고리즘 : 층 별로 원하는 값을 미리 할당해놓고 정답에 해당하는 값을 찾아낼 수 있다
        int qSize = q.size();
        for (int i = 0; i < qSize; i++)
        {
            int x = q.front();
            q.pop();
            for (int nx : {x - 1, x + 1, x * 2})
            {
                if (nx < 0 || nx > MAX || visited[turn % 2][nx]) continue;
                visited[turn % 2][nx] = visited[(turn + 1) % 2][x] + 1;
                if (nx == k) // 동생이 미리 도착
                {
                    ok = true;
                    break;
                }
                q.push(nx);
            }
            if (ok) break;
        }
        if (ok) break;
        turn++;
    }

    if (ok) cout << turn << '\n';
    else cout << -1 << '\n';

    return 0;
}

평가

  • 도착점이 고정되어 있는 일반적인 BFS 문제와는 다르게 도착점도 동시에 이동하는 BFS 문제로 도착점인 동생의 값을 turn이라는 변수와 함께 증가 시켜 나가면서 풀이하는 것이 중요했던 문제
  • 수빈이가 이동을 진행하면서 동시에 동생을 만나는 경우와 수빈이가 먼저 도착을 한적이 있고 그 후에 동생이 그 위치에 오는 경우 두가지로 나누어서 알고리즘을 구성
    • 이 과정에서 visited 배열을 50만 * 50만으로 전부 짤 필요 없이 홀수, 짝수의 개념만 가지고 공간 복잡도를 최소화 할 수 있다
  • flood fill 알고리즘
    • 다차원 배열의 어떤 칸과 연결된 영역을 찾는 알고리즘 (색칠 알고리즘)
    • 홀짝으로 visited[2][동생의 위치] 값을 찾아가며 턴별로 q에 담아서 확인하기

© 2023 Jinsoo Lee. All rights reserved.

Powered by Hydejack v9.1.6