PS/Implementation

백준 23289번: 온풍기 안녕! (Java)

닻과매 2022. 7. 28. 11:24

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

 

23289번: 온풍기 안녕!

유난히 추운 날씨가 예상되는 이번 겨울을 대비하기 위해 구사과는 온풍기를 설치하려고 한다. 온풍기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기

www.acmicpc.net

 

 

 

 

 

 

 

 


 

풀이

한 번의 과정은 5단계로 나뉩니다.

 

1) 온풍기에서 바람이 나감

 - 가장 어려운 부분이었습니다.

 - 각 칸마다 바람이 퍼질 수 있는지 bfs/dfs로 판정하면 됩니다.

 - 저는 가로벽을 해당칸에 1, 세로벽을 해당칸에 2로 나타내어 비트처리해줬습니다.

 - 4방향을 다 한꺼번에 처리할 수도 있겠으나, 생각이 잘 안나서 저는 하드코딩 했습니다.

  - 그리고 여기서 오타나서 고생했습니다. 이게 방향처리 한번에 하려고 하면 힘들고, 또 막상 하드코딩하면 오타때문에 실수나고..어떻게 해야할지 잘 모르겠네요.

2) 열이 퍼짐

 - 쓰여진 대로 구현하면 됩니다. 새로운 배열 만들어서 변화를 기록해두세요. 

3) 모서리 식음

 - 꼭지점을 2번 세지 않도록 for문을 모서리별로 나누어서 처리해줍니다.

4) 초콜릿을 먹음

 - 왜 초콜릿일까요?

5) 검사

 - 하면 됩니다.

 

 

코드

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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import java.io.*;
import java.util.*;
 
public class Main {
 
    static int[] dr = { 000-11 };
    static int[] dc = { 01-100 };
    static int R, C, K;
    static int[][] wall, map;
    static boolean[][] visited;
    static List<int[]> heaters = new ArrayList<>();
    static List<int[]> checks = new ArrayList<>();
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        map = new int[R+1][C+1];
        wall = new int[R+1][C+1];
        
        for (int i = 1; i <= R; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= C; j++) {
                int x = Integer.parseInt(st.nextToken());
                if (x == 0continue;
                if (x < 5) {
                    heaters.add(new int[] {i, j, x});
                }
                else {
                    checks.add(new int[] {i, j});
                }
            }
        }
        
        int W = Integer.parseInt(br.readLine());
        for (int i = 0; i < W; i++) {
            st = new StringTokenizer(br.readLine());
            int r = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            int t = Integer.parseInt(st.nextToken());
            wall[r][c] += (t+1);
        }        
        
        int choco = 0;
        while (true) {
            heat();
            spread();
            coolBorder();
            choco++;
            if (choco > 100break;
            if (check()) break;
        }
        System.out.println(choco);
    }
    
    static void heat() {
        for (int[] h: heaters) {
            visited = new boolean[R+1][C+1]; // 되려나...
            int r = h[0], c = h[1], dir = h[2];
            if (isIn(r + dr[dir], c + dc[dir])) oneHeater(r + dr[dir], c + dc[dir], dir, 5);
        }
    }
    
    static void oneHeater(int r, int c, int dir, int temp) {
        if (temp == 0return;
        visited[r][c] = true;
        map[r][c] += temp;
        
        if (dir == 1) {
            try { 
                int nr = r-1, nc = c+1;
                if (isIn(nr, nc) && !visited[nr][nc]) {
                    if (!isWall(r, c, 0&& !isWall(r-1, c, 1)) {
                        oneHeater(nr, nc, dir, temp-1);
                    }
                }
                nr++;
                if (isIn(nr, nc) && !visited[nr][nc]) {
                    if (!isWall(r, c, 1)) {
                        oneHeater(nr, nc, dir, temp-1);
                    }
                }
                nr++;
                if (isIn(nr, nc) && !visited[nr][nc]) {
                    if (!isWall(r+1, c, 0&& !isWall(r+1, c, 1)) {
                        oneHeater(nr, nc, dir, temp-1);
                    }
                }
            } catch (Exception e) {
                throw new ArithmeticException();
            }
        }
        else if (dir == 2) {
            int nr = r+1, nc = c-1;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r+1, c, 0&& !isWall(r+1, c-11)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nr--;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c-11)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nr--;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c, 0&& !isWall(r-1, c-11)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
        }
        else if (dir == 3) {
            int nr = r-1, nc = c-1;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c-10&& !isWall(r, c-11)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nc++;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c, 0)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nc++;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c, 1&& !isWall(r, c+10)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
        }
        else {
            int nr = r+1, nc = c-1;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c-11&& !isWall(r+1, c-10)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nc++;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r+1, c, 0)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
            nc++;
            if (isIn(nr, nc) && !visited[nr][nc]) {
                if (!isWall(r, c, 1&& !isWall(r+1, c+10)) {
                    oneHeater(nr, nc, dir, temp-1);
                }
            }
        }
    }
    
    static void spread() {
        int[][] tempMap = new int[R+1][C+1];
        for (int r = 1; r <= R; r++) {
            for (int c = 1; c <= C; c++) {
                int nr = r + dr[1], nc = c + dc[1];
                if (isIn(nr, nc) && map[r][c] > map[nr][nc] && !isWall(r, c, 1)) {
                    int diff = (map[r][c] - map[nr][nc]) / 4;
                    tempMap[nr][nc] += diff;
                    tempMap[r][c] -= diff;
                }
                nr = r + dr[2];
                nc = c + dc[2];
                if (isIn(nr, nc) && map[r][c] > map[nr][nc] && !isWall(r, c-11)) {
                    int diff = (map[r][c] - map[nr][nc]) / 4;
                    tempMap[nr][nc] += diff;
                    tempMap[r][c] -= diff;
                }
                nr = r + dr[3];
                nc = c + dc[3];
                if (isIn(nr, nc) && map[r][c] > map[nr][nc] && !isWall(r, c, 0)) {
                    int diff = (map[r][c] - map[nr][nc]) / 4;
                    tempMap[nr][nc] += diff;
                    tempMap[r][c] -= diff;
                }
                nr = r + dr[4];
                nc = c + dc[4];
                if (isIn(nr, nc) && map[r][c] > map[nr][nc] && !isWall(r+1, c, 0)) {
                    int diff = (map[r][c] - map[nr][nc]) / 4;
                    tempMap[nr][nc] += diff;
                    tempMap[r][c] -= diff;
                }
            }
        }
        
        for (int r = 1; r <= R; r++) {
            for (int c = 1; c <= C; c++) {
                map[r][c] += tempMap[r][c];
            }
        }
    }
    
    static void coolBorder() {
        for (int c = 1; c <= C; c++) {
            if (map[1][c] > 0) map[1][c]--;
        }
        for (int r = 2; r <= R; r++) {
            if (map[r][C] > 0) map[r][C]--;
        }
        for (int c = C-1; c >= 1; c--) {
            if (map[R][c] > 0) map[R][c]--;
        }
        for (int r = 2; r < R; r++) {
            if (map[r][1> 0) map[r][1]--;
        }
    }
    
    static boolean check() {
        for (int[] c: checks) {
            if (map[c[0]][c[1]] < K) return false;
        }
        return true;
    }
    
    static boolean isIn(int r, int c) {
        return !(r <= 0 || r > R || c <= 0 || c > C);
    }
    
    static boolean isWall(int r, int c, int t) {
        return (wall[r][c] & (t+1)) > 0;
    }
}
cs

 

 

 

P.S.

진짜 죽을 맛의 디버깅이었습니다...