본문 바로가기
코딩테스트

[백준2151] 거울 설치

by 근즈리얼 2023. 12. 21.
728x90

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

 

2151번: 거울 설치

첫째 줄에 집의 크기 N (2 ≤ N ≤ 50)이 주어진다. 다음 N개의 줄에는 N개의 문자로 집에 대한 정보가 주어진다. ‘#’는 문이 설치된 곳으로 항상 두 곳이며, ‘.’은 아무 것도 없는 것으로 빛은

www.acmicpc.net

 

백준 2151 거울 설치 문제입니다.

 

다익스트라를 활용해서 풀었습니다.

 


문제 풀이

 

먼저 알아야 할 것

  • 거울을 둘 수 있는 곳과 빛이 통과할 수 있는 곳의 가중치를 다르게 둔다.
  • 거울을 둘 수  있는 곳은 빛이 들어온 방향의 직선, 왼쪽, 오른쪽으로 빛을 보낼 수있다.
  • 거울을 둘 수 없는 곳은 빛이 들어온 같은 방향으로만 빛을 보낼 수 있다.

 

중요한 개념

  • 다른 다익스트라 문제와 마찬가지로 방문 여부를 체크하기 위해 visit이 필요합니다. 다만, 이 문제는 어디서 빛이 들어왔는지 알아야 하기 때문에 boolean[][][] visit으로 만듭니다.
  • 보통  dx = {-1,1,0,0}, dy = {0,0,-1,1} 이렇게 다음 x,y의 값을 구하기 위해서 배열을 사용합니다. 여기서 dx[0]과 dy[0]은 -1,0 임을 확인할 수 있고 그림 상에서는 위로 간 것을 알 수  있습니다. 따라서, 위로 올라갔는데 거울을 둘 수 있는 지점이면 위, 오른쪽, 왼쪽으로 빛을 또 보낼 수 있는 것입니다. 여기서 오른쪽으로 보내기 위해서는 3번째 인덱스를 넣어줘야 하고 왼쪽으로 보내기 위해서는 2번째 인덱스를 넣어야 합니다. (코드로 확인해보시면 더 이해하기 쉬울겁니다!)

코드

package codingtest.baek2151;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;

public class Main {

    static char[][] map;
    static boolean[][][] visit;
    static int sx, sy, ex, ey, N;
    static int[] dx = {-1,1,0,0};
    static int[] dy = {0,0,-1,1};
    static int[] d1 = {2,3,1,0};
    static int[] d2 = {3,2,0,1};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());

        map = new char[N][N];
        visit = new boolean[N][N][4];

        int index = 0;
        for(int i = 0; i<N;i++) {
            char[] charArray = br.readLine().toCharArray();
            for(int j = 0; j<N;j++) {
                map[i][j] = charArray[j];
                if(map[i][j] == '#' && index == 0) {
                    index++;
                    sx = i;
                    sy = j;
                }
                if(map[i][j] == '#' && index == 1) {
                    ex = i;
                    ey = j;
                }
            }
        }

        dijkstra();
    }

    private static void dijkstra() {
        PriorityQueue<Node> p = new PriorityQueue<>((o1,o2) -> o1.cnt - o2.cnt);

        // 0 : 왼, 1 : 오, 2 : 아래, 3 : 위
        for(int i = 0; i<4; i++) {
            p.add(new Node(sx, sy, i,0));
        }

        int min = 0;
        while (!p.isEmpty()) {
            Node now = p.poll();

            if(!visit[now.x][now.y][now.d]) {
                visit[now.x][now.y][now.d] = true;

                if(now.x == ex && now.y == ey) {
                    min = now.cnt;
                    break;
                }

                int nx = now.x + dx[now.d];
                int ny = now.y + dy[now.d];

                if(nx >= 0 && ny >=0 && nx <N && ny < N && map[nx][ny] != '*') {
                    if(map[nx][ny] == '!') {
                        int tmp = now.cnt;
                        p.add(new Node(nx,ny,d1[now.d], tmp+1));
                        p.add(new Node(nx,ny,d2[now.d], tmp+1));
                    }
                    p.add(new Node(nx,ny, now.d, now.cnt));
                }
            }
        }
        System.out.println(min);
    }

    static class Node{
        int x;
        int y;
        int d;
        int cnt;

        public Node(int x, int y, int d, int cnt) {
            this.x = x;
            this.y = y;
            this.d = d;
            this.cnt = cnt;
        }
    }
}
728x90

'코딩테스트' 카테고리의 다른 글

[백준 1946] 신입사원  (2) 2024.01.03
[백준 18223] 민준이와 마산 그리고 건우  (0) 2023.12.29
[백준 1010] 다리 놓기  (2) 2023.12.05
[백준 17928] 오큰수[java]  (0) 2021.11.05
[백준 1874] 스택 수열 [java]  (0) 2021.11.05

댓글