-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path최하라.java
134 lines (113 loc) · 3.77 KB
/
최하라.java
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
import java.io.*;
import java.util.*;
public class Main {
static int N, M, count, years;
static int[][] map, tmpMap;
static Deque<Coord> iceberg;
static int[] dx = new int[] { 0, 0, -1, 1 };
static int[] dy = new int[] { -1, 1, 0, 0 };
static boolean[][] visit;
static class Coord {
int x, y;
Coord(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// Set variables
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
// Build map
map = new int[N][M];
iceberg = new ArrayDeque<>();
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] != 0) {
// Store iceberg coord
iceberg.add(new Coord(i, j));
}
}
}
years = 0;
while (true) {
years++;
updateIceberg();
int group = checkGroup();
if (group >= 2)
break;
else if (group == 0) {
years = -1;
break;
}
}
System.out.println(years == -1 ? 0 : years);
}
static void updateIceberg() {
tmpMap = new int[N][M];
int icebergLeng = iceberg.size();
// Update each iceberg height into tmpMap
for (int i = 0; i < icebergLeng; i++) {
Coord current = iceberg.pollFirst();
int currX = current.x;
int currY = current.y;
// count number of water
count = 0;
for (int dir = 0; dir < 4; dir++) {
int mx = dx[dir] + currX;
int my = dy[dir] + currY;
if (mx < 0 || my < 0 || mx >= N || my >= M)
continue;
if (map[mx][my] <= 0)
count++;
}
iceberg.addLast(new Coord(currX, currY));
tmpMap[currX][currY] = map[currX][currY] - count;
}
// Update base Map using new iceberg height
for (int i = 0; i < icebergLeng; i++) {
Coord current = iceberg.pollFirst();
int currX = current.x;
int currY = current.y;
// Above 0 -> iceberg
if (tmpMap[currX][currY] > 0)
iceberg.addLast(new Coord(currX, currY));
// Update iceberg height on base map
map[currX][currY] = tmpMap[currX][currY];
}
}
static int checkGroup() {
int count = 0;
// No iceberg exist
if (iceberg.isEmpty())
return 0;
// Check iceberg group
int icebergLeng = iceberg.size();
visit = new boolean[N][M];
for (int i = 0; i < icebergLeng; i++) {
Coord current = iceberg.pollFirst();
if (!visit[current.x][current.y]) {
checkSurrounding(current.x, current.y);
count++; // count group
}
iceberg.addLast(new Coord(current.x, current.y));
}
return count;
}
static void checkSurrounding(int x, int y) {
visit[x][y] = true;
for (int dir = 0; dir < 4; dir++) {
int mx = dx[dir] + x;
int my = dy[dir] + y;
if (mx < 0 || my < 0 || mx >= N || my >= M)
continue;
if (map[mx][my] > 0 && !visit[mx][my]) {
checkSurrounding(mx, my);
}
}
}
}