백준 온라인 저지/Gold

[BOJ] 13549 - 숨바꼭질 3

jooona 2021. 2. 23. 00:52
반응형

개인적인 풀이일 뿐, 최적의 정답이 아님을 알려드립니다.

 

문제

www.acmicpc.net/problem/13549

 

13549번: 숨바꼭질 3

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

www.acmicpc.net

난이도: 골드 5

사용언어: JAVA

 

풀이

비록 이차원이 아닌 일차원 배열에 입력이 들어가지만, 이 문제는 BFS를 사용하여 접근하는 것이 가장 이해하기 쉽습니다. 기존에 이차원 배열에서 상하좌우로 이동하던 것을, 좌우로 한 칸씩, 또는 2배씩 이동시키는 것으로 변형한다고 생각하면 됩니다. BFS에 관한 설명은 아래 문제의 풀이에서 확인하실 수 있습니다.

 

jooona.tistory.com/63

 

[BOJ] 2178 - 미로 탐색

-개인적인 풀이일 뿐, 최적의 정답이 아님을 알려드립니다. 문제 설명 www.acmicpc.net/problem/2178 2178번: 미로 탐색 첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로..

jooona.tistory.com

 

그리고 한 가지 고려해야 할 사항은 목표 지점인 K에 도달했다고 해서 섣불리 결과를 출력해서는 안됩니다. 혹시 그 뒤에 (2*X 연산을 더 많이 해서) 시간 값이 더 작은 수빈이가 도착할 수도 있기 때문입니다. 따라서 적어도 큐에 저장되어 있는 수빈이들은 다 확인을 한 뒤에 최소 시간을 판단해야 합니다.

 

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import java.io.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
class Main {
 
    static class position{
        int pos;
        int second;
    }
 
    static Queue<position> q= new LinkedList<>();
    static int []d = {1,-1};
    static int N, K;
    static int result;
    static int count = 2;
    static int flag = 0;
    public static void bfs(position p, int arr[]){
        int i;
        for(i=0;i<2;i++){
            if(p.pos+d[i] >= 0 && p.pos+d[i] <=100000 && (arr[p.pos+d[i]] == 0||arr[p.pos+d[i]] == count)){ // 위치가 범위내에 있고, 아직 아무도 검사하지 않았거나, 해당 사이클 안에서만 검사되었을 경우
                if(p.pos+d[i] == K){ // 동생을 찾았다면
                    result = Math.min(p.second+1,result); // 결과 저장
                    flag = 1;
                }
                else{
                    arr[p.pos+d[i]] = count; // 카운트 값을 넣어줌으로써 이미 방문했던 곳임을 마킹
                }
                position p1 = new position();
                p1.pos = p.pos+d[i];
                p1.second = p.second + 1; // 한 칸 이동하는 데에는 1초가 소요
                q.add(p1); // 위치와 현재까지의 소요시간을 큐에 삽입
            }
            if(p.pos*2*d[i] >= 0 && p.pos*2*d[i] <=100000 &&  (arr[p.pos*2*d[i]] == 0||arr[p.pos*2*d[i]] == count)){ // 위치가 범위내에 있고, 아직 아무도 검사하지 않았거나, 해당 사이클 안에서만 검사되었을 경우
                if(p.pos*2*d[i] == K){ // 동생을 찾았다면
                    result = Math.min(p.second,result); // 결과 저장
                    flag = 1;
                }
                else{
                    arr[p.pos*2*d[i]] =count; // 카운트 값을 넣어줌으로써 이미 방문했던 곳임을 마킹
                }
                position p2 = new position();
                p2.pos = p.pos*2*d[i];
                p2.second = p.second; // 순간이동에는 0초가 소요
                q.add(p2); // 위치와 현재까지의 소요시간을 큐에 삽입
            }
        }
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        int[]arr = new int[100001]; // 수빈이가 움직일 수 있는 곳 배열
        int i, k;
        position p = new position();
 
        if(N == K){ // 수빈이와 동생이 같은 곳에 위치하는 경우 예외 처리

            System.out.println(0);
            System.exit(0);
        }
        p.pos = N;
        p.second = 0;
        q.add(p); // 수빈이의 현재 위치와 현재까지 소요시간인 0을 큐에 삽입
        arr[p.pos] = 1; // count 값을 1은 여기서 넣어주기 때문에 2부터 시작
 
        result = Integer.MAX_VALUE;
        while(true){ // 이 while 문 한 번을 한 사이클이라고 하자.
            k = q.size();
            for(i=0;i<k;i++){
                p = q.remove(); // 큐에서 하나씩 빼서
               bfs(p, arr); // bfs 수행
            }
            if(flag == 1){ // K에 도달했다면
                System.out.println(result); // 결과 출력
                System.exit(0);
            }
            count++; //count는 이미 왔던 곳을 다시 검사하지 않기 위해, 그리고 한 사이클 안에서는 한 수빈이가 특정 지점에 먼저 도착하더라도 다른 수빈이가 검사를 할 수 있도록 해주는데 사용
        }
    }
}
 
 
cs

 

반응형

'백준 온라인 저지 > Gold' 카테고리의 다른 글

[BOJ] 2096 - 내려가기  (0) 2021.02.24
[BOJ] 1987 - 알파벳  (0) 2021.02.23
[BOJ] 2206 - 벽 부수고 이동하기  (0) 2021.02.22
[BOJ] 2352 - 반도체 설계  (0) 2021.02.22
[BOJ] 5427 - 불  (0) 2021.02.21