문제풀이/백준oj

[백준OJ] 16985번 Maaaaaaaaaze - Java

Hyeon-Uk 2022. 12. 31. 01:55
반응형

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

 

16985번: Maaaaaaaaaze

첫째 줄부터 25줄에 걸쳐 판이 주어진다. 각 판은 5줄에 걸쳐 주어지며 각 줄에는 5개의 숫자가 빈칸을 사이에 두고 주어진다. 0은 참가자가 들어갈 수 없는 칸, 1은 참가자가 들어갈 수 있는 칸을

www.acmicpc.net


풀이

모든 경우의수를 다 대입해서 탐색했습니다.

순서에 대한 모든 경우를 결정한 뒤, 결정된 배열의 각 층을 모두 돌려서 모든 경우를 구한 뒤, BFS를 통해 최소경로를 찾았습니다. 

이때 어차피 모든 경우의 수를 다 탐색하기때문에, 임의로 입구를 (0,0,0), 출구를 (4,4,4)로 고정해도 문제가 해결됩니다.

시간복잡도

순서를 정하는 경우의 수 O(5!), 각 순서를 정한 뒤, 모든층에 대해 회전하는 경우의 수 O(4*4*4*4*4) , BFS O(5*5*5) 기 때문에, 최종 경우의 수는 O(5! * 4^5 * 5^3) 이 됩니다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int[][][] maze = new int[5][5][5];
    static int[][][] copy = new int[5][5][5];

    static boolean[] visited = new boolean[5];
    static int answer = Integer.MAX_VALUE;
    static int[][] mv = new int[][]{{0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}};

    public static class Node {
        int x, y, z;

        public Node(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

    public static boolean isIn(int x, int y, int z) {
        return 0 <= x && x < 5 && 0 <= y && y < 5 && 0 <= z && z < 5;
    }

    public static void bfs() {
        if (copy[0][0][0] == 0) {
            return;
        }

        Queue<Node> q = new LinkedList<>();
        int[][][] dist = new int[5][5][5];
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                for (int k = 0; k < 5; k++) {
                    dist[i][j][k] = Integer.MAX_VALUE;
                }
            }
        }

        q.offer(new Node(0, 0, 0));
        dist[0][0][0] = 0;

        while (!q.isEmpty()) {
            Node node = q.poll();
            int x = node.x;
            int y = node.y;
            int z = node.z;
            int d = dist[x][y][z];

            if (x == 4 && y == 4 && z == 4) {
                answer = Math.min(answer, dist[x][y][z]);
                return;
            }
            for (int dd = 0; dd < mv.length; dd++) {
                int nx = x + mv[dd][0];
                int ny = y + mv[dd][1];
                int nz = z + mv[dd][2];
                if (isIn(nx, ny, nz) && dist[nx][ny][nz] > d + 1 && copy[nx][ny][nz] == 1) {
                    q.offer(new Node(nx, ny, nz));
                    dist[nx][ny][nz] = d + 1;
                }
            }
        }
    }

    public static void dfs(int index) {
        if (index == 5) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    for (int k = 0; k < 4; k++) {
                        for (int l = 0; l < 4; l++) {
                            for (int m = 0; m < 4; m++) {
                                bfs();
                                copy[4] = turn(copy[4]);
                            }
                            copy[3] = turn(copy[3]);
                        }
                        copy[2] = turn(copy[2]);
                    }
                    copy[1] = turn(copy[1]);
                }
                copy[0] = turn(copy[0]);
            }
            return;
        }

        for (int i = 0; i < 5; i++) {
            if (visited[i]) continue;

            visited[i] = true;
            for (int x = 0; x < 5; x++) {
                for (int y = 0; y < 5; y++) {
                    copy[index][x][y] = maze[i][x][y];
                }
            }
            dfs(index + 1);
            visited[i] = false;
        }
    }


    public static int[][] turn(int[][] maze) {
        int[][] cp = new int[5][5];

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                cp[i][j] = maze[5 - j - 1][i];
            }
        }
        return cp;
    }


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                for (int k = 0; k < 5; k++) {
                    maze[i][j][k] = Integer.valueOf(st.nextToken());
                }
            }
        }

        dfs(0);
        System.out.println(answer == Integer.MAX_VALUE ? -1 : answer);

    }
}
반응형