ALGORITHM/PROGRAMMERS

[프로그래머스] 경주로 건설 (2020 카카오 인턴십)

0298 2021. 3. 2. 22:25

programmers.co.kr/learn/courses/30/lessons/67259

 

코딩테스트 연습 - 경주로 건설

[[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,1],[0,0,1,0,0,0,1,0],[0,1,0,0,0,1,0,0],[1,0,0,0,0,0,0,0]] 3800 [[0,0,1,0],[0,0,0,0],[0,1,0,1],[1,0,0,0]] 2100 [[0,0,0,0,0,0],[0,1,1,1,1,0],[0,0,1,0,0,0],[1,0,0,1,0,1],[

programmers.co.kr

2021-03-02


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import java.util.LinkedList;
import java.util.Queue;
 
public class Solution67259 {
    static class Doro {
        int x;
        int y ;
        int prev;
        int cost;
 
        public Doro(int x, int y, int prev, int cost) {
            this.x = x;
            this.y = y;
            this.prev = prev;
            this.cost = cost;
        }
    }
 
    public static int[] dx = {-1010};
    public static int[] dy = {0-101};
 
    public static int solution(int[][] board) {
        int answer = 987654321;
 
        int N = board.length;
        Queue<Doro> q = new LinkedList<>();
        boolean[][] vtd = new boolean[N][N]; // 방문체크
        int[][] map = new int[N][N]; // 방문한 곳 비용 체크
        q.add(new Doro(0020)); // 아래
        q.add(new Doro(0030)); // 오른쪽
        vtd[0][0= true;
 
 
        while(!q.isEmpty()) {
            Doro tmp = q.poll();
            int x = tmp.x;
            int y = tmp.y;
            int prev = tmp.prev;
            int cost = tmp.cost;
            if(x == N-1 && y == N-1) answer = Math.min(answer, cost); // 원하는 위치(N-1, N-1)에 도달하면 answer최소값 체크
 
            for(int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                //범위를 벗어나거나 || 벽이 있거나 || 거꾸로 돌아가는 경우
                if(nx < 0 || ny < 0 || nx >= N || ny >= N || board[nx][ny] == 1 || ((prev+2) % 4 == i)) continue;
 
                int newCost = cost;
                if((prev % 2 == 0 && i % 2 == 0|| (prev % 2 != 0 && i % 2 != 0)) newCost += 100;
                else newCost += 600;
 
                if(!vtd[nx][ny]) { // 방문한적이 없다면
                    vtd[nx][ny] = true;
                    map[nx][ny] = newCost;
                    q.add(new Doro(nx, ny, i, newCost));
                } else if (map[nx][ny] >= (newCost)) { // 방문한적이 있다면, 비용 비교해서 갱신
                    map[nx][ny] = newCost;
                    q.add(new Doro(nx, ny, i , newCost));
                }
            }
        }
 
        return answer;
    }
    public static void main(String[] args) {
//        int[][] b = {{0,0,0},{0,0,0},{0,0,0}};
        int[][] b = {
                {00000001},
                {00000000},
                {00000100},
                {00001000},
                {00010001},
                {00100010},
                {01000100},
                {10000000}
        };
        System.out.println(solution(b));
 
    }
}
 
cs

#문제풀이

 

BFS + 방문한적이 있는 곳은 비용을 비교해서 갱신 시켜준다.

 

단순히 방문한적이 있는 곳을 다시는 방문하지 못하도록 한다면, 기존보다 더 최소비용으로 건설할 수 있음에도 건설하지 못하는 경우가 생긴다. 그래서 각각의 최소비용을 계속해서 업데이트 할 수 있도록 map[][]을 이용한다.