[백준 17071번] 숨바꼭질 5

2021. 11. 25. 01:06·알고리즘 문제풀이/백준
반응형

문제 링크: https://www.acmicpc.net/problem/17071

 

17071번: 숨바꼭질 5

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

www.acmicpc.net

<문제 풀이> BFS

수빈이가 정점 n에 있을 때 시간을 t라고 하면 동생의 위치는 (등차수열의 합 공식을 사용해서 구하면)

k + t*(t+1)/2에 있습니다.

 

수빈이의 위치와 시간을 저장하는 큐를 만들고 BFS를 돌리고

큐에서 pop을 할 때  t초 후 동생과 수빈이가 n에서 만나는지를 확인하면 됩니다.

 

그런데 n 제한이 50만이기 때문에 여기서 모든 정점을 큐에 넣으면 시간 초과, 메모리 초과가 나게 됩니다.

적절하게 방문 체크를 해서 이미 큐에 넣은 정점은 큐에 다시 넣지 않게 해야 됩니다.

 

문제의 입력을 트리 형태로 그려보면 수빈이가 정점 n을 t초에 방문했을 때 짝수 초 후에 그 정점을 다시 방문할 수 있다는 것을 알 수 있습니다. 

(-1 -> +1 하면 제자리)

 

그러면 BFS를 진행하면 정점 n일 때 레벨 t을 알 수 있으니깐 t초 일 때 동생의 위치 n을 구해서

수빈이가 위치 n을 짝수 초에 방문했는지, 홀수 초에 방문했는지를 visited 배열로 체크하면 됩니다.

(만약 수빈이가 홀수 초에만 n에 방문하고 동생이 짝수 초에만 n에 방문하면 서로 만날 수 없음)

 

<C++ 소스 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <utility>
#include <climits>
using namespace std;
 
#define X first 
#define Y second 
 
int n, k; 
bool visited[500001][2];
 
int bfs() {
    queue<pair<int, int> > Q;
    Q.push({ n, 0 });
    visited[n][0] = true;
    while (!Q.empty()) {
        auto cur = Q.front(); Q.pop();
        if (k + cur.Y * (cur.Y + 1) / 2 > 500000) {
            return -1;
        }
        if (visited[k + cur.Y * (cur.Y + 1) / 2][cur.Y % 2]) {
            return cur.Y;
        }
        if (2 * cur.X <= 500000 && !visited[2 * cur.X][(cur.Y + 1) % 2]) {
            Q.push({2 * cur.X, cur.Y + 1 });
            visited[2 * cur.X][(cur.Y + 1) % 2] = cur.Y + 1;
        }
        if (cur.X + 1 <= 500000 && !visited[cur.X + 1][(cur.Y + 1) % 2]) {
            Q.push({cur.X + 1, cur.Y + 1 });
            visited[cur.X + 1][(cur.Y + 1) % 2] = cur.Y + 1;
        }
        if (cur.X - 1 >= 0 && !visited[cur.X - 1][(cur.Y + 1) % 2]) {
            Q.push({cur.X - 1, cur.Y + 1 });
            visited[cur.X - 1][(cur.Y + 1) % 2] = cur.Y + 1;
        }
    }
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n >> k;
    cout << bfs();
    return 0;
}
 
Colored by Color Scripter
cs

 

반응형
저작자표시 (새창열림)

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

[백준 4963번] 섬의 개수  (0) 2021.11.25
[백준 1600번] 말이 되고픈 원숭이  (0) 2021.11.25
[백준 12851번] 숨바꼭질2  (0) 2021.11.22
[백준 13913번] 숨바꼭질4  (0) 2021.11.21
[백준 6593번] 상범 빌딩  (0) 2021.11.19
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 4963번] 섬의 개수
  • [백준 1600번] 말이 되고픈 원숭이
  • [백준 12851번] 숨바꼭질2
  • [백준 13913번] 숨바꼭질4
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (199)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (1)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    다이나믹 프로그래밍
    코틀린을 활용한 안드로이드 프로그래밍
    구현
    콘솔 테트리스 게임
    dfs
    알고리즘
    콘솔
    백준
    Kotlin
    백트랙킹
    BFS
    그래프
    그리디
    우선순위 큐
    자료구조
    C
    코틀린
    시뮬레이션
    dp
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 17071번] 숨바꼭질 5
상단으로

티스토리툴바