Algorithm

[Programmers] 블록 게임

프로그래민 2020. 8. 22. 15:49
반응형

단순 시뮬레이션 문제이다.

문제에 주어진 조건처럼 단순히 모든 경우수를 체크하는 방식으로 풀어보았다. 다음과 같은 로직으로 해결해보았다.
1. 모든 도형은 3개의 연속블록을 가지므로 가로, 세로로 나누어 3개가 연속이 되는 블럭을 찾음
2. 그 블럭에서 튀어나온 블록 하나를 찾음
3. 튀어나온 블록과 동일선상에 있는 검정블록 2개에 대해 위에서 떨어트릴 수 있는지 체크
4. 가능하다면 답+1

위와 같은 로직이지만 코드는 좀 어지럽게 나왔다. 리팩토링을 해보아야겠다.

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package programmers;
 
public class Solution_2019카카오_블록게임 {
    
    
    static int[] di = {-1,-1,-1,1,1,1,0,1,2,0,1,2};
    static int[] dj = {0,1,2,0,1,2,1,1,1,-1,-1,-1};
    static int[][] map;
    static int answer;
    
    public static void main(String[] args) {
        
        int[][] board= {
                {0,0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,4,0,0,0},
                {0,0,0,0,0,0,4,0,0,0},
                {0,0,0,0,3,0,4,4,0,0},
                {0,0,0,2,3,0,0,0,0,5},
                {1,2,2,2,3,3,0,0,0,5},
                {1,1,1,0,0,0,0,0,5,5}
            };
        
        System.out.println(solution(board));
    }
    
    static int solution(int [][] board) {
        answer=0;
        
        int row=board.length;
        int col=board[0].length;
        map=new int[row][col];
        for(int i=0;i<row;i++) {
            for(int j=0;j<row;j++)
                map[i][j]=board[i][j];
        }
        boolean[] visit;
        
        while(true) {
            int prevAnswer=answer;
            visit=new boolean[3000];
            
            loop: for(int i=0;i<row;i++) {
                for(int j=0;j<=col-3;j++) {
                    int num = map[i][j];
                    if(num!=0 && visit[num]==false) {
                        if(checkHorizontal(i, j)) {
 
                            funcHorizontal(i,j);
                            visit[num]=true;
                            
                            if(prevAnswer!=answer)
                                break loop;
                        }
                    }
                }
            }
            
            if(prevAnswer == answer) {    //세로검사
                loop2: for(int i=0;i<=row-3;i++) {
                    for(int j=0;j<col;j++) {
                        int num = map[i][j];
                        if(num!=0 && visit[num]==false) {
                            if(checkVertical(i, j)) {
                                funcVertical(i,j);
                                visit[num]=true;
                                if(prevAnswer!=answer)
                                    break loop2;
                            }
                        }
                    }
                }
            }
            
            if(prevAnswer==answer)
                break;
            
//            for(int i=0;i<row;i++) {
//                for(int j=0;j<col;j++) {
//                    System.out.print(map[i][j]);
//                }
//                System.out.println();
//            }
//            System.out.println("==========================");
        }
        
        return answer;
    }
    
    static boolean checkHorizontal(int i,int j) {
        if(map[i][j] == map[i][j+1&& map[i][j+1== map[i][j+2])
            return true;
        return false;
    }
    static boolean checkVertical(int i,int j) {
        if(map[i][j] == map[i+1][j] && map[i+1][j] == map[i+2][j])
            return true;
        return false;
    }
    
    static void funcHorizontal(int i,int j) {
        for(int dir=0;dir<6;dir++) {     //한칸 찾기
            int nextI=i+di[dir];        
            int nextJ=j+dj[dir];
            
            if(isValid(nextI,nextJ) && map[i][j]==map[nextI][nextJ]) {
                //찾은한칸을 제외한 두개 확인
                if (dir == 0  && go(nextI,nextJ+1&& go(nextI,nextJ+2) ) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ+1]=map[nextI][nextJ+2]=0;
                    answer+=1;
                }else if(dir==1 && go(nextI,nextJ-1&& go(nextI,nextJ+1)) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ-1]=map[nextI][nextJ+1]=0;
                    answer+=1;
                }else if(dir==2 && go(nextI,nextJ-1&& go(nextI,nextJ-2)) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ-1]=map[nextI][nextJ-2]=0;
                    answer+=1;
                }else if(dir==3 && go(nextI,nextJ+1&& go(nextI,nextJ+2)) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ+1]=map[nextI][nextJ+2]=0;
                    answer+=1;
                }else if(dir==4 && go(nextI,nextJ-1&& go(nextI,nextJ+1)) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ-1]=map[nextI][nextJ+1]=0;
                    answer+=1;
                }else if(dir==5 && go(nextI,nextJ-1&& go(nextI,nextJ-2)) {
                    map[i][j]=map[i][j+1]=map[i][j+2]=map[nextI][nextJ]=map[nextI][nextJ-1]=map[nextI][nextJ-2]=0;
                    answer+=1;
                }
                break;
            }
        }
    }
    
    static void funcVertical(int i,int j) {
        for(int dir=6;dir<12;dir++) {     //한칸 찾기
            int nextI=i+di[dir];        
            int nextJ=j+dj[dir];
            
            if(isValid(nextI,nextJ) && map[i][j]==map[nextI][nextJ]) {
                //찾은한칸을 제외한 두개 확인
                if (dir == 6  && go(nextI+1,nextJ) && go(nextI+2,nextJ) ) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI+1][nextJ]=map[nextI+2][nextJ]=0;
                    answer+=1;
                }else if(dir==7 && go(nextI-1,nextJ) && go(nextI+1,nextJ)) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI-1][nextJ]=map[nextI+1][nextJ]=0;
                    answer+=1;
                }else if(dir==8 && go(nextI-1,nextJ) && go(nextI-2,nextJ)) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI-1][nextJ]=map[nextI-1][nextJ]=0;
                    answer+=1;
                }else if(dir==9 && go(nextI+1,nextJ) && go(nextI+2,nextJ)) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI+1][nextJ]=map[nextI+2][nextJ]=0;
                    answer+=1;
                }else if(dir==10 && go(nextI-1,nextJ) && go(nextI+1,nextJ)) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI-1][nextJ]=map[nextI+1][nextJ]=0;
                    answer+=1;
                } else if (dir == 11 && go(nextI-1,nextJ) && go(nextI-2,nextJ)) {
                    map[i][j]=map[i+1][j]=map[i+2][j]=map[nextI][nextJ]=map[nextI-1][nextJ]=map[nextI-2][nextJ]=0;
                    answer+=1;
                }
                break;
            }
        }
    }
    
    static boolean isValid(int i,int j) {
        if(i<0 || i>=map.length || j<0 || j>=map[0].length)
            return false;
        return true;
    }
    
    static boolean go(int i,int j) {
        if(map[i][j]!=0)
            return false;
        for(int row=0;row<i;row++) {
            if(map[row][j]!=0)
                return false;
        }
        return true;
    }
}
 
                
반응형

'Algorithm' 카테고리의 다른 글

[BOJ] 1188. 음식 평론가  (0) 2020.08.28
[BOJ] 1992. 쿼드트리  (0) 2020.08.27
[Programmers] 길 찾기 게임  (0) 2020.08.16
[BOJ] 9466. 텀 프로젝트  (4) 2020.08.15
[Programmers] 문자열 압축  (0) 2020.08.12