거울설치


백준 [2151] 거울설치

문제보기

풀이

  • BFS
  • DFS

BFS

Alt text

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

Alt text

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;
	}
}