처음에 봤을 때
1. 모든 칸을 돌면서 동시에 visited[][] 갱신하면서, 국경선 열지 판단하는 것
2. 한번 열면 다 합쳐서 sum / N 해서 갱신하는 것
3. 차이가 L~R일 때까지 위 과정을 반복하는 것..
이라고 생각하고 코드를 짰다.
처음에 코드를 구현했을 때 잘못된 점은
ArrayList<int[]> union = new ArrayList<>();를 선언해서 연합 지역을 관리 및 계산해야한다는 게 핵심이다.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class BOJ_16234_인구이동_G4 {
static int N, L, R;
static int[][] arr;
static boolean[][] visited;
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
L = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
arr = new int[N][N];
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
int day = 0;
while (true) {
visited = new boolean[N][N];
boolean moved = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
if (isOpen(i, j)) moved = true;
}
}
}
if (!moved) break;
day++;
}
System.out.println(day);
}
public static boolean isOpen(int x, int y) {
// 여기선 bfs로 4방향을 탐색해야함
Queue<int[]> q = new LinkedList<>();
ArrayList<int[]> union = new ArrayList<>();
q.add(new int[]{x, y});
union.add(new int[]{x, y});
visited[x][y] = true;
int sum = arr[x][y];
while (!q.isEmpty()) {
int[] cur = q.poll();
int cx = cur[0];
int cy = cur[1];
for (int d = 0; d < 4; d++) {
int nx = cx + dx[d];
int ny = cy + dy[d];
if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
if (visited[nx][ny]) continue;
int diff = Math.abs(arr[cx][cy] - arr[nx][ny]);
if (diff >= L && diff <= R) {
visited[nx][ny] = true;
q.add(new int[]{nx, ny});
union.add(new int[]{nx, ny});
sum += arr[nx][ny];
}
}
}
// 연합이 2개 이상이면 인구 이동 발생
if (union.size() > 1) {
int avg = sum / union.size();
for (int[] p : union) {
arr[p[0]][p[1]] = avg;
}
return true;
}
return false;
}
}