공부공간

BOJ -1697 ) 숨바꼭질 본문

알고리즘/완전탐색(BFS,DFS)

BOJ -1697 ) 숨바꼭질

개발자가될수있을까? 2020. 1. 19. 23:51

 

 


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

1697번: 숨바꼭질

문제 수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다. 수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지

www.acmicpc.net


수빈이가 동생의 위치로 가는 경로중 가장 짧은 시간으로 찾아가는 경우의 수를 구하는 문제이다.

문제의 구현은 어렵지않았지만 사소한 오류때문에 조금생각을 해야했다.

 

1. 동생의 위치가 수빈이보다 뒤에 있는 경우

수빈이는 뒤로는 1칸 갈수있으므로 이경우에는 K-N을 빠르게 리턴한다.

 

2. 같은 위치의 경우 

바로 0 을 리턴한다.

 

3. 동생이 수빈이보다 앞에있어서 3가지의 경우로 전진하는 경우

 

Q를 이용하여서 갈수있는 경우와 시간을 같이 넣어준다.

Q에 들어간 갈수있는 경우가 동생의 위치와 일치하면 종료한다.


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
53
54
55
56
#include <iostream>
#include <queue>
using namespace std;
int N, K, time;
bool visit[100001];
typedef struct {
    int now, time;
 
}pos;
int main(void) {
    cin >> N >> K;
    if (K < N) {
        cout << N - K;
    }
    else if (N == K) {
        cout << 0;
    }
    else {
 
        pos start = { N , 0 };
        queue < pos > Q;
        Q.push(start);
        int now = N;
        while (!Q.empty()) {
 
            now = Q.front().now;
            time = Q.front().time;
            if (now == K) break;
            Q.pop();
 
            if (now + 1 <= 100000 && !visit[now + 1]) {
                visit[now + 1= true;
                Q.push({ now + 1 , time + 1 });
            }
            if (2 * now <= 100000 && !visit[2 * now]) {
 
                visit[2 * now] = true;
                Q.push({ 2 * now , time + 1 });
            }
            if (now - 1 >= 0 && !visit[now - 1]) {
                visit[now - 1= true;
                Q.push({ now - 1 , time + 1 });
 
            }
 
        }
        cout << time;
 
 
 
 
    }
 
 
    return 0;
}
 
 

 

 


간단하게 풀릴줄 알았는데 

 

메모리 초과를 받았었다. Q에 많이 넣어서 날수도 있겠다고 생각했었는데,

 

어떤 한 위치에 대해서 여러번 큐에 들어갈 수 있기에 visit 배열을 100001 크기로 잡아주어서 

 

실행하였더니 런타임 에러가 났다.

 

즉 테스트케이스를 넣어볼때에 2 * now 의 값이 100000을 넘는경우도 포함된다는 말이였다.

 

if( visit[ 2 * now ] && 2 * now <= 100001)

위의 경우는 런타임 에러가 나지만

if( 2 * now <= 100001 && visit[ 2 * now ])

이 경우는 나지 않는다.

 

즉 배열의 인덱스값을 확인하는 과정에서 now의 범위 체크를 먼저 해주고 배열을 찾아가야지만 항상 유효한 인덱스에 

 

접근할 수 있다.

 

배열 인덱스를 참고할 때에 이러한 부분을 기억해야겠다.

'알고리즘 > 완전탐색(BFS,DFS)' 카테고리의 다른 글

BOJ - 7569 ) 토마토  (0) 2020.01.22
BOJ - 1002 ) 적록색약 JAVA  (0) 2020.01.20
BOJ - 7576 ) 토마토  (0) 2020.01.19
BOJ - 5427 ) 불  (0) 2020.01.17
BOJ - 7562 ) 나이트의 이동  (0) 2020.01.17
Comments