connecting the dots
[BOJ/Java] 16234 : 인구이동 본문
문제
16234번: 인구 이동
N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모
www.acmicpc.net
풀이
처음에 조금 헤맸지만, 알고보니 쉬운 문제였다. BFS를 사용해 연결된 연합을 찾고 visited 처리해주어서 다시 방문하지 않도록 한다. 연합을 찾을 때마다 해당 맵을 update 해준다!
코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int[][] dir = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
static int[][] map;
static int N, L, R;
static boolean isMove;
static boolean[][] visited;
public static void main(String[] args) throws Exception {
st = new StringTokenizer(in.readLine());
N = Integer.parseInt(st.nextToken());
L = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
map = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(in.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int count = 0;
while (true) {
visited = new boolean[N][N];
isMove = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) { //방문하지 않은 곳에 BFS를 돌림
BFS(i, j);
}
}
}
if (!isMove) //인구이동이 일어나지 않았으면 break
break;
count++;
}
System.out.println(count);
}
private static void BFS(int i, int j) {
Queue<Node> moveArea = new LinkedList<>();//이동한 영역 list
Queue<Node> queue = new LinkedList<>();//bfs를 위한 큐
queue.add(new Node(i, j));
moveArea.add(new Node(i, j));
visited[i][j] = true;
int sum = 0;
sum += map[i][j];
while (!queue.isEmpty()) {
int x = queue.peek().x;
int y = queue.peek().y;
queue.poll();
for (int d = 0; d < 4; d++) {
int dx = x + dir[d][0];
int dy = y + dir[d][1];
if (dx < 0 || dy < 0 || dx >= N || dy >= N)
continue;
if (visited[dx][dy])
continue;
int diff = Math.abs(map[x][y] - map[dx][dy]);
if (diff >= L && diff <= R) { // 이웃 나라와의 차가 L이상 R이하일 때
visited[dx][dy] = true;//해당 나라 방문
moveArea.add(new Node(dx, dy));//인구이동할 list에 넣어줌
queue.add(new Node(dx, dy));
sum += map[dx][dy];//연합의 총 인구를 구하기 위해 더해줌
}
}
}
int avg = 0;
if (moveArea.size() > 1) { //연합이 만들어졌다면(인구이동이 일어날 수 있다면)
avg = sum / moveArea.size();
isMove = true;
while (!moveArea.isEmpty()) {//연합 내에 있는 나라 인구를 평균값으로 바꿔줌
map[moveArea.peek().x][moveArea.peek().y] = avg;
moveArea.poll();
}
}
}
static class Node {
int x, y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
}
느낀점
- 스스로 생각하는게 어렵다 ㅠㅠ
'algorithm > BOJ' 카테고리의 다른 글
[BOJ/Java] 2644 : 촌수계산 (0) | 2021.03.17 |
---|---|
[BOJ/Java] 14502 : 연구소 (0) | 2021.03.16 |
[BOJ/Java] 17140 : 이차원 배열과 연산 (0) | 2021.03.16 |
[BOJ/Java] 2564 : 경비원 (0) | 2021.02.26 |
[BOJ/Java] 2573 : 빙산 (0) | 2021.02.20 |