문제풀이/백준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);
}
}
반응형