백준 온라인 저지/Gold

[BOJ] 20058 - 마법사 상어와 파이어스톰

jooona 2021. 10. 6. 00:44
반응형

개인적인 풀이일 뿐, 최적의 정답이 아님을 알려드립니다.

 

문제

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

 

20058번: 마법사 상어와 파이어스톰

마법사 상어는 파이어볼과 토네이도를 조합해 파이어스톰을 시전할 수 있다. 오늘은 파이어스톰을 크기가 2N × 2N인 격자로 나누어진 얼음판에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c

www.acmicpc.net

난이도: 골드 4

사용언어: JAVA

 

풀이

구현 문제는 하라는 대로 다 해주면 되죠?

 

제가 처음 구현할 때 간과했던 부분만 짚고 넘어가겠습니다.

 

1. 얼음을 삭제할 때 Queue에 담아서 삭제해 줄 것. 그렇지 않으면 이전에 삭제한 얼음이 다음 얼음에 영향을 미칠 수 있다.

2. 얼음을 0 이하의 정수로 감소시키지 말 것. 나중에 남은 얼음의 합을 구할 때 오답을 구하게 됨.

3. 입력 받은 L값이 0일 경우 변환을 시키지 말 것. 하지만 얼음 삭제는 시켜야 함.

 

참고로 회전은 temp라는 배열을 하나 선언해서 원래 배열의 값의 위치를 변환하여 temp에 저장하는 식으로 구현했습니다.

 

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
import java.io.*;
import java.util.*;
 
public class Main {
 
    static int N;
    static int Q;
    static int[][] arr;
    static int[][] temp;
    static boolean[][] visit;
    static int L;
    static int np;
    static int sum = 0;
    static int max = 0;
    static int count = 0;
 
    static class position {
        int x;
        int y;
 
        position(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
 
    static Queue<position> q = new LinkedList<>(); // 반드시 큐를 이용하여 얼음을 감소시킬 것.
 
    static void change(int fx, int fy, int range) {
        while (range >= 2) {
            for (int i = 0; i < range; i++) {
                temp[fx + i][fy + range - 1= arr[fx][fy + i];
                temp[fx + range - 1][fy + range - 1 - i] = arr[fx + i][fy + range - 1];
                temp[fx + i][fy] = arr[fx + range - 1][fy + i];
                temp[fx][fy + range - 1 - i] = arr[fx + i][fy];
            }
 
            fx += 1;
            fy += 1;
            range -= 2;
        }
 
    }
 
    static int[][] d = { { -10 }, { 01 }, { 10 }, { 0-1 } };
 
    public static void check(int x, int y) {
        int nx, ny;
        int chk = 0;
        for (int i = 0; i < 4; i++) {
            nx = x + d[i][0];
            ny = y + d[i][1];
 
            if (nx < 0 || ny < 0 || nx >= np || ny >= np || temp[nx][ny] < 1) {
                continue;
            }
            chk++;
        }
        if (chk < 3 && temp[x][y] > 0) { // 0 이하로 얼음을 내려가게 하지 말 것.
            q.add(new position(x, y));
        }
    }
 
    public static void dfs(int x, int y) {
        int nx, ny;
        for (int i = 0; i < 4; i++) {
            nx = x + d[i][0];
            ny = y + d[i][1];
 
            if (nx < 0 || ny < 0 || nx >= np || ny >= np || arr[nx][ny] < 1 || visit[nx][ny] == true) {
                continue;
            }
 
            visit[nx][ny] = true;
            count++;
            dfs(nx, ny);
 
        }
 
    }
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        N = sc.nextInt();
        Q = sc.nextInt();
        np = (int) Math.pow(2, N);
        arr = new int[np][np];
        temp = new int[np][np];
 
        for (int i = 0; i < np; i++) {
            for (int j = 0; j < np; j++) {
                arr[i][j] = sc.nextInt();
            }
        }
 
        for (int times = 0; times < Q; times++) {
            L = sc.nextInt();
            if (L > 0) { // L이 0이면 얼음 감소만 시킬 것.
                int mp = (int) Math.pow(2, L);
 
                for (int i = 0; i < np; i += mp) {
                    for (int j = 0; j < np; j += mp) {
                        change(i, j, mp);
                    }
                }
            } else {
                for (int i = 0; i < np; i++) {
                    for (int j = 0; j < np; j++) {
                        temp[i][j] = arr[i][j];
                    }
                }
            }
 
            for (int i = 0; i < np; i++) {
                for (int j = 0; j < np; j++) {
                    check(i, j);
                    arr[i][j] = temp[i][j];
                }
            }
            while (!q.isEmpty()) {
                position p = q.poll();
                arr[p.x][p.y]--;
            }
        }
 
        visit = new boolean[np][np];
        for (int i = 0; i < np; i++) {
            for (int j = 0; j < np; j++) {
                if (arr[i][j] > 0)
                    sum += arr[i][j];
                if (visit[i][j] == false && arr[i][j] > 0) {
                    visit[i][j] = true;
                    count = 1;
                    dfs(i, j);
                    max = Math.max(count, max);
                }
            }
        }
 
        System.out.println(sum);
        System.out.println(max);
 
    }
}
cs

 

반응형

'백준 온라인 저지 > Gold' 카테고리의 다른 글

[BOJ] 2116 - 주사위 쌓기  (0) 2022.01.31
[BOJ] 10423 - 전기가 부족해  (2) 2021.10.21
[BOJ] 16174 - 점프왕 쩰리 (Large)  (0) 2021.05.13
[BOJ] 1261 - 알고스팟  (1) 2021.04.22
[BOJ] 1584 - 게임  (0) 2021.04.19