PS/Implementation

백준 20061번: 모노미노도미노 2 (Java)

닻과매 2022. 7. 15. 19:58

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

 

20061번: 모노미노도미노 2

모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,

www.acmicpc.net

 

 

 

 

 

 

 

 


 

풀이

지문 길이를 보는 순간 한숨이 나옵니다. '아니, 이런 거 까지 풀어야 하나?' 하는 생각이 들지만, 마음을 가다듬고 지문을 읽어보면 생각보다 요구하는 바가 명확하며, 구현도 생각보다 쉽습니다.

 

코드

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
import java.io.*;
import java.util.*;
 
public class Main {
 
    // place() method 구현을 편하게 하고자
    // row = col = 10인 곳에 기본적으로 '쌓여있는' 처리
    static boolean[][] map = new boolean[11][11];
    static int score = 0;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        for (int i = 0; i < 10; i++) {
            map[10][i] = true;
            map[i][10= true;
        }
        while (N-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int t = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            place(t, x, y);
            erase();
            push();
        }
        System.out.println(score);
        System.out.println(count());
    }
    
    // 도형을 배치하기
    static void place(int t, int x, int y) {
        switch (t) {
        case 1:
            for (int i = 6; i <= 10; i++) {
                if (map[i][y]) {
                    map[i-1][y] = true;
                    break;
                }
            }
            for (int j = 6; j <= 10; j++) {
                if (map[x][j]) {
                    map[x][j-1= true;
                    break;
                }
            }
            break;
        case 2:
            for (int i = 6; i <= 10; i++) {
                if (map[i][y] || map[i][y+1]) {
                    map[i-1][y] = true;
                    map[i-1][y+1= true;
                    break;
                }
            }
            for (int j = 6; j <= 10; j++) {
                if (map[x][j]) {
                    map[x][j-1= true;
                    map[x][j-2= true;
                    break;
                }
            }
            break;
        case 3:
            for (int i = 6; i <= 10; i++) {
                if (map[i][y]) {
                    map[i-1][y] = true;
                    map[i-2][y] = true;
                    break;
                }
            }
            for (int j = 6; j <= 10; j++) {
                if (map[x][j] || map[x+1][j]) {
                    map[x][j-1= true;
                    map[x+1][j-1= true;
                    break;
                }
            }
            break;
        }
    }
    
    // 4줄을 차지하여 점수를 얻는 행/열 찾기
    // 점수 더하고 한 칸씩 옮겨 해당 행/열 지우기
    static void erase() {
        int cnt = 4;
        int row = 9, col = 9;
        while (cnt-- > 0) {
            if (map[row][0&& map[row][1&& map[row][2&& map[row][3]) {
                score++;
                for (int i = row; i > 3; i--) {
                    for (int j = 0; j < 4; j++) {
                        map[i][j] = map[i-1][j];
                    }
                }
                row++;
            }
            if (map[0][col] && map[1][col] && map[2][col] && map[3][col]) {
                score++;
                for (int j = col; j > 3; j--) {
                    for (int i = 0; i < 4; i++) {
                        map[i][j] = map[i][j-1];
                    }
                }
                col++;
            }
            row--;
            col--;
        }
    }
    
    // 연한 영역을 얼마나 차지하는 지 센 후
    // 그 수만큼 밀어버리기
    static void push() {
        int greenPush = 0, bluePush = 0;
        for (int i = 4; i < 6; i++) {
            if (map[i][0|| map[i][1|| map[i][2|| map[i][3]) greenPush++;
            if (map[0][i] || map[1][i] || map[2][i] || map[3][i]) bluePush++;
        }
        
        while (greenPush-- > 0) {
            for (int i = 9; i > 3; i--) {
                for (int j = 0; j < 4; j++) {
                    map[i][j] = map[i-1][j];
                }
            }
        }
        while (bluePush-- > 0) {
            for (int j = 9; j > 3; j--) {
                for (int i = 0; i < 4; i++) {
                    map[i][j] = map[i][j-1];
                }
            }
        }
    }
    
    // 차지하는 영역을 계산하는 method
    static int count() {
        int ret = 0;
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                if (map[i][j]) ret++;
            }
        }
        return ret;
    }
}
 
cs