CS/알고리즘_KAKAO BLIND RECRUITMENT

2021 KAKAO BLIND RECRUITMENT : 카드 짝 맞추기(리뷰 필요)

Jedy_Kim 2021. 10. 13. 14:01
728x90

https://programmers.co.kr/learn/courses/30/lessons/72415

 

코딩테스트 연습 - 카드 짝 맞추기

[[1,0,0,3],[2,0,0,0],[0,0,0,2],[3,0,1,0]] 1 0 14 [[3,0,0,2],[0,0,1,0],[0,1,0,0],[2,0,0,3]] 0 1 16

programmers.co.kr

 

// 코드

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import java.util.*;
 
class Solution {
    
    static final int INF = Integer.MAX_VALUE;
    static final int[][] dir = {{-10}, {10}, {0-1}, {01}};
    int[][] Board;
    
    class Point {
        // 행, 열, 조작 횟수
        int row, col, cnt;
        
        Point(int row, int col, int cnt) {
            this.row = row;
            this.col = col;
            this.cnt = cnt;
        }
        
    }
    
    int bfs(Point src, Point dst) {
        
        boolean[][] visited = new boolean[4][4];
        Deque<Point> deq = new ArrayDeque<>();
        
        deq.add(src);
        while(!deq.isEmpty()) {
            Point curr = deq.pop();            
            if(curr.row == dst.row && curr.col == dst.col) 
                return curr.cnt;
            
            for(int i=0; i<4++i) {
                int nr = curr.row + dir[i][0], nc = curr.col + dir[i][1];                
                if(nr < 0 || nr > 3 || nc < 0 || nc > 3continue;
                
                if(!visited[nr][nc]) {
                    visited[nr][nc] = true;
                    deq.add(new Point(nr, nc, curr.cnt + 1));
                }
                
                for(int j=0; j<2++j) {
                    if(Board[nr][nc] != 0break;
                    if(nr + dir[i][0< 0 || nr + dir[i][0> 3 
                      || nc + dir[i][1< 0 || nc + dir[i][1> 3break;
                    
                    nr += dir[i][0];
                    nc += dir[i][1];                    
                }
                
                if(!visited[nr][nc]) {
                    visited[nr][nc] = true;
                    deq.add(new Point(nr, nc, curr.cnt + 1));
                }
                
            }
            
        }
        
        return INF;
    }
    
    int permutate(Point src) {
        int ret = INF;
        
        // 1~6번 까지 카드
        for(int num=1; num<=6++num) {
            List<Point> card = new ArrayList<>();
            // 해당 카드의 위치를 찾는다.
            for(int i=0; i<4++i) {
                for(int j=0; j<4++j) {
                    if(Board[i][j] == num) {
                        card.add(new Point(i, j, 0));
                    }
                }
            }
            
            if(card.isEmpty()) continue;
            
            //두 개의 카드를 뒤집는다.
            int one = bfs(src, card.get(0)) 
                + bfs(card.get(0), card.get(1)) + 2;
            
            int two = bfs(src, card.get(1)) 
                + bfs(card.get(1), card.get(0)) + 2;
            
            // 카드를 뒤집었으니 해당카드를 지워준다.
            for(int i=0; i<2; i++
                Board[card.get(i).row][card.get(i).col] = 0;            
            
            ret = Math.min(ret, one + permutate(card.get(1)));
            ret = Math.min(ret, two + permutate(card.get(0)));
            
            // 뒤집었던 카드를 복원해준다.
            for(int i=0; i<2; i++
                Board[card.get(i).row][card.get(i).col] = num;
            
        }
        
        if(ret == INF) return 0;
    
        return ret;
    }
    
    public int solution(int[][] board, int r, int c) {        
        Board = board;        
        return permutate(new Point(r, c, 0));
    }
}
cs

 

반응형