백준 [2151] 거울설치
문제보기
풀이
BFS
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Main {
static int N, ans;
static char[][] map;
static int[][] door;
static int[] dx = { -1, 1, 0, 0 }; // 상하좌우
static int[] dy = { 0, 0, -1, 1 };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
ans = 987654321;
map = new char[N][N];
door = new int[2][2];
int idx = 0;
for (int i = 0; i < N; i++) {
String str = br.readLine();
for (int j = 0; j < N; j++) {
map[i][j] = str.charAt(j);
if (map[i][j] == '#') {
door[idx][0] = i;
door[idx][1] = j;
idx++;
}
}
}
setMirror();
System.out.println(ans);
}
// bfs
public static void setMirror() {
Queue<int[]> queue = new LinkedList<>();
int[][][] v = new int[2][N][N]; // 0: '/', 1: 역슬래쉬
// [2]방향 [3]거울갯수
queue.add(new int[] { door[0][0], door[0][1], 0, 0 });
queue.add(new int[] { door[0][0], door[0][1], 1, 0 });
queue.add(new int[] { door[0][0], door[0][1], 2, 0 });
queue.add(new int[] { door[0][0], door[0][1], 3, 0 });
while (!queue.isEmpty()) {
int[] q = queue.poll();
if (q[3] >= ans)
continue;
int x = q[0] + dx[q[2]];
int y = q[1] + dy[q[2]];
while (isRange(x, y) && map[x][y] != '*') {
if (x == door[1][0] && y == door[1][1]) {
ans = Math.min(ans, q[3]);
break;
}
if (map[x][y] == '!') {
boolean flag1 = false;
boolean flag2 = false;
// 설치 안하고 가는경우
queue.add(new int[] { x, y, q[2], q[3] });
// 설치 하고 가는경우
if (v[0][x][y] == 0 || (v[0][x][y] != 0 && v[0][x][y] > q[3] + 1)) {
v[0][x][y] = q[3] + 1;
flag1 = true;
}
if (v[1][x][y] == 0 || (v[1][x][y] != 0 && v[1][x][y] > q[3] + 1)) {
v[1][x][y] = q[3] + 1;
flag2 = true;
}
if (!flag1 && !flag2)
break;
int dir1 = -1;
int dir2 = -1;
if (q[2] == 0) {
dir1 = 3;
dir2 = 2;
} else if (q[2] == 1) {
dir1 = 2;
dir2 = 3;
} else if (q[2] == 2) {
dir1 = 1;
dir2 = 0;
} else if (q[2] == 3) {
dir1 = 0;
dir2 = 1;
}
if (flag1) { // '/'
queue.add(new int[] { x, y, dir1, q[3] + 1 });
}
if (flag2) { // '\'
queue.add(new int[] { x, y, dir2, q[3] + 1 });
}
}
x = x + dx[q[2]];
y = y + dy[q[2]];
}
}
}
public static boolean isRange(int x, int y) {
return x >= 0 && y >= 0 && x < N && y < N;
}
}
DFS
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Main {
static int N, ans;
static char[][] map;
static int[][] door;
static int[] dx = { -1, 1, 0, 0 }; // 상하좌우
static int[] dy = { 0, 0, -1, 1 };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
ans = 987654321;
map = new char[N][N];
door = new int[2][2];
int idx = 0;
for (int i = 0; i < N; i++) {
String str = br.readLine();
for (int j = 0; j < N; j++) {
map[i][j] = str.charAt(j);
if (map[i][j] == '#') {
door[idx][0] = i;
door[idx][1] = j;
idx++;
}
}
}
v = new int[2][N][N];
setMirror(door[0][0], door[0][1], 0, 0);
v = new int[2][N][N];
setMirror(door[0][0], door[0][1], 1, 0);
v = new int[2][N][N];
setMirror(door[0][0], door[0][1], 2, 0);
v = new int[2][N][N];
setMirror(door[0][0], door[0][1], 3, 0);
System.out.println(ans);
}
// dfs
static int[][][] v;
public static void setMirror(int r, int c, int dir, int cnt) {
if (cnt >= ans) {
return;
}
int x = r + dx[dir];
int y = c + dy[dir];
while (isRange(x, y) && map[x][y] != '*') {
if (x == door[1][0] && y == door[1][1]) {
ans = Math.min(ans, cnt);
return;
}
if (!isRange(x, y) || map[x][y] == '*')
return;
if(v[0][x][y] != 0 && v[0][x][y] <= cnt + 1) {
return;
}
if(v[1][x][y] != 0 && v[1][x][y] <= cnt + 1) {
return;
}
if (map[x][y] == '!') {
// 거울 설치 안하고 그냥 지나가기
setMirror(x, y, dir, cnt);
// 거울 설치 하고 지나가기
int dir1 = -1;
int dir2 = -1;
if (dir == 0) {
dir1 = 3;
dir2 = 2;
} else if (dir == 1) {
dir1 = 2;
dir2 = 3;
} else if (dir == 2) {
dir1 = 1;
dir2 = 0;
} else if (dir == 3) {
dir1 = 0;
dir2 = 1;
}
if (v[0][x][y] == 0 || (v[0][x][y] != 0 && v[0][x][y] > cnt + 1)) {
v[0][x][y] = cnt + 1;
setMirror(x, y, dir1, cnt + 1);
}
if (v[1][x][y] == 0 || (v[1][x][y] != 0 && v[1][x][y] > cnt + 1)) {
v[1][x][y] = cnt + 1;
setMirror(x, y, dir2, cnt + 1);
}
}
x = x + dx[dir];
y = y + dy[dir];
}
}
public static boolean isRange(int x, int y) {
return x >= 0 && y >= 0 && x < N && y < N;
}
}