(백준) 20543번 - 폭탄 던지는 태영이
(백준) 20543번 - 폭탄 던지는 태영이
(백준) 20543번 - 폭탄 던지는 태영이
##
https://www.acmicpc.net/problem/20543
풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void reset(int x, int y) {
for (int i = x - m / 2; i <= x + m / 2; i++) {
for (int j = y - m / 2; j <= y + m / 2; j++) {
after[i][j] += before[x][y];
}
}
}
// ...
for (int i = m / 2; i < n - m / 2; i++) {
for (int j = m / 2; j < n - m / 2; j++) {
before[i][j] = -after[i - 1][j - 1];
reset(i, j);
}
}
처음에는 폭탄 위치를 찾고, $M \times M$ 배열을 일일이 순회하며 보정해서 TLE이 발생했다. 적절한 폭탄 위치를 찾는 데 $O((N-M)^2)$, 폭탄 영역을 순회하는 데 $O(M^2)$이었기에 전체 시간복잡도는 $O((NM)^2)$이었다.
1
2
3
4
5
0 0 0 0 0
0 2 0 2 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
폭탄이 위와 같이 설치되었다고 하자. 터진 후 고도를 이차원 누적 합으로 구해보자.
1
2
3
4
5
-2 0 0 2 0
0 0 0 0 0
-2 0 0 2 0
2 0 0 -2 0
0 0 0 0 0
위와 같은 이차원 누적 합 배열을 만든 후, 왼쪽으로 한 번, 아래쪽으로 한 번 스위핑하면 될 것이다.
배열을 입력받고, 역순으로 스위핑을 수행하여 위 배열을 만든 후 폭탄의 위치를 구했다.
코드
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
package boj.boj_20543;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n, m;
static long[][] result, tmp1, tmp2, ans;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
StringTokenizer st = new StringTokenizer(line);
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
result = new long[n][n];
tmp1 = new long[n][n];
tmp2 = new long[n][n];
ans = new long[n][n];
for (int i = 0; i < n; i++) {
line = br.readLine();
st = new StringTokenizer(line);
for (int j = 0; j < n; j++) {
result[i][j] = Long.parseLong(st.nextToken());
}
}
// 이차원 배열 누적 합을 역순으로 진행한다.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
tmp1[i][j] = result[i][j] - (j > 0 ? result[i][j - 1] : 0);
}
}
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
tmp2[i][j] = tmp1[i][j] - (i > 0 ? tmp1[i - 1][j] : 0);
}
}
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
System.out.print(tmp2[i][j]);
}
System.out.println();
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (tmp2[i][j] < 0) {
if (i + m / 2 < n && j + m / 2 < n) {
ans[i + m / 2][j + m / 2] = -tmp2[i][j];
}
if (i + m < n && j + m < n) tmp2[i + m][j + m] -= tmp2[i][j];
if (i + m < n) tmp2[i + m][j] += tmp2[i][j];
if (j + m < n) tmp2[i][j + m] += tmp2[i][j];
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sb.append(ans[i][j]).append(' ');
}
sb.append('\n');
}
System.out.println(sb);
}
}
시간복잡도
모든 반복문에서 $N$에 대해 이중 for문을 돌고 있으므로 전체 시간복잡도는 $O(N^2)$이다.
공간복잡도
사용하는 배열이 전부 $N \times N$ 배열이므로 전체 공간복잡도는 $O(N^2)$이다.
This post is licensed under CC BY 4.0 by the author.