Post

[BaekJoon] 16933번 - 벽 부수고 이동하기 3 [Java][C++]

[BaekJoon] 16933번 - 벽 부수고 이동하기 3 [Java][C++]

문제 링크


1. 문제 풀이


BaekJoon 14442번 - 벽 부수고 이동하기 2 문제에서 낮과 밤이 추가되어 벽은 낮에만 부술 수 있으며 이동하지 않고 머물 수도 있는 문제로 방문 체크에서 낮과 밤도 상태로 추가해주면 된다. 탐색중 벽을 만나면 낮일 경우 동일하게 풀고 밤일 경우 flagtrue로 설정해서 이동하지 않는 경우를 고려해줬다.


2. 코드


1. 풀이 [Java]

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
87
88
89
90
91
92
93
94
import java.io.*;
import java.util.*;

public class Main {

    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int n, m;
    static char[][] grid;

    static class Node {
        int r, c;
        int x;
        int day;  // 낮=0, 밤=1

        public Node(int r, int c, int x, int day) {
            this.r = r;
            this.c = c;
            this.x = x;
            this.day = day;
        }
    }

    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());
        m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        grid = new char[n][m];
        for (int i = 0; i < n; i++) {
            grid[i] = br.readLine().toCharArray();
        }

        System.out.println(bfs(k));
    }

    static int bfs(int k) {
        Queue<Node> q = new ArrayDeque<>();
        q.offer(new Node(0, 0, 0, 0));

        boolean[][][][] visited = new boolean[n][m][1 + k][2];
        visited[0][0][0][0] = true;

        int dist = 1;

        while (!q.isEmpty()) {
            int size = q.size();

            while (size-- > 0) {
                Node node = q.poll();
                if (node.r == n - 1 && node.c == m - 1) return dist;

                boolean flag = false;
                for (int d = 0; d < 4; d++) {
                    int nr = node.r + dr[d];
                    int nc = node.c + dc[d];

                    if (nr < 0 || nr >= n || nc < 0 || nc >= m) continue;

                    if (grid[nr][nc] == '0') {
                        if (visited[nr][nc][node.x][1 - node.day]) continue;

                        q.offer(new Node(nr, nc, node.x, 1 - node.day));
                        visited[nr][nc][node.x][1 - node.day] = true;
                    } else {
                        if (node.day == 0) {
                            if (node.x >= k) continue;
                            if (visited[nr][nc][node.x + 1][1 - node.day]) continue;

                            q.offer(new Node(nr, nc, node.x + 1, 1 - node.day));
                            visited[nr][nc][node.x + 1][1 - node.day] = true;
                        } else {
                            flag = true;
                        }
                    }
                }

                if (flag) {
                    if (visited[node.r][node.c][node.x][1 - node.day]) continue;

                    q.offer(new Node(node.r, node.c, node.x, 1 - node.day));
                    visited[node.r][node.c][node.x][1 - node.day] = true;
                }
            }

            dist++;
        }

        return -1;
    }
}


2. 풀이 [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
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
#include <bits/stdc++.h>
using namespace std;

int dr[4] = {-1, 0, 1, 0};
int dc[4] = {0, 1, 0, -1};
int n, m, k;
char grid[1001][1001];
bool visited[1001][1001][11][2];

struct Node {
    int r, c, x, day;
};

int bfs() {
    queue<Node> q;
    q.push({0, 0, 0, 0});

    visited[0][0][0][0] = true;

    int dist = 1;

    while (!q.empty()) {
        int sz = q.size();

        while (sz--) {
            auto [r, c, x, day] = q.front();
            q.pop();

            if (r == n - 1 && c == m - 1) return dist;

            bool flag = false;
            for (int d = 0; d < 4; d++) {
                int nr = r + dr[d];
                int nc = c + dc[d];

                if (nr < 0 || nr >= n || nc < 0 || nc >= m) continue;

                if (grid[nr][nc] == '0') {
                    if (visited[nr][nc][x][1 - day]) continue;

                    q.push({nr, nc, x, 1 - day});
                    visited[nr][nc][x][1 - day] = true;
                } else {
                    if (day == 0) {
                        if (x >= k) continue;
                        if (visited[nr][nc][x + 1][1 - day]) continue;

                        q.push({nr, nc, x + 1, 1 - day});
                        visited[nr][nc][x + 1][1 - day] = true;
                    } else {
                        flag = true;
                    }
                }
            }

            if (flag) {
                if (visited[r][c][x][1 - day]) continue;

                q.push({r, c, x, 1 - day});
                visited[r][c][x][1 - day] = true;
            }
        }

        dist++;
    }

    return -1;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m >> k;

    for (int i = 0; i < n; i++) {
        cin >> grid[i];
    }

    cout << bfs();
}

This post is licensed under CC BY 4.0 by the author.