• Home
  • About
    • Ryureka Moment photo

      Ryureka

      Sin Prisa, Sin Pausa

    • About Me
    • Facebook
    • Github
    • Youtube
  • Projects
  • Posts
    • Posts
    • ProblemSolvings
    • Tags
    • Blog
    • Examples
  • ProblemSolving
    • ProblemSolving
    • BOJ
    • Programmers
    • SWEA
    • LeetCode
  • FrontEnd
    • FrontEnd
    • HTML
  • BackEnd
    • BackEnd
    • Server
      • Server
      • Spring
      • NodeJS
    • DataBase
      • DataBase
      • MySQL
      • MongoDB
  • Programming
    • Programming
    • Java
    • JS
    • Python
    • CleanCode
  • ComputerScience
    • DataStructure
    • Algorithm

[BOJ] 16234. 인구이동

16 Apr 2026

Reading time ~4 minutes

  • 풀이
  • 다른 풀이

풀이

import java.util.*;

public class Main {
	public static int N, L, R;
	public static int day = 0;
	public static int[][] map;
	public static int[][] group;
	public static int[] dy = {1, 0, -1, 0};
	public static int[] dx = {0, 1, 0, -1};

	public static void bfs(int y, int x, int groupCnt) {
		ArrayList<Point> list = new ArrayList<>();
		Queue<Point> q = new LinkedList<>();
		q.add(new Point(y, x));
		group[y][x] = groupCnt;
		int sum = map[y][x];
		int cnt = 1;
		list.add(new Point(y, x));

		while (!q.isEmpty()) {
			Point p = q.poll();
			for (int i = 0; i < 4; i++) {
				int ny = p.y + dy[i];
				int nx = p.x + dx[i];
				if (ny < 0 || ny >= N || nx < 0 || nx >= N) continue;
				if(group[ny][nx] == -1) {
					int dif = Math.abs(map[ny][nx] - map[p.y][p.x]);
					if (L <= dif && dif <= R) {
						q.add(new Point(ny, nx));
						group[ny][nx] = groupCnt;
						sum += map[ny][nx];
						cnt++;
						list.add(new Point(ny, nx));
					}
				}
			}
		}

		for (int i = 0; i < list.size(); i++) {
			y = list.get(i).y;
			x = list.get(i).x;
			map[y][x] = sum / cnt;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		L = sc.nextInt();
		R = sc.nextInt();
		map = new int[N][N];
		group = new int[N][N];
        
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				map[i][j] = sc.nextInt();
			}
		}

		while (true) {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					group[i][j] = -1;
				}
			}
			int groupCnt = 0;
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					if (group[i][j] == -1) {
						bfs(i, j, groupCnt);
						groupCnt++;
					}
				}
			}
			if (groupCnt == N * N) break;
			day++;
		}
		System.out.println(day);
	}

	static class Point {
		public int y, x;
		
		public Point(int y, int x) {
			this.y = y;
			this.x = x;
		}
	}
}

문제를 푸는 데 세 가지 정도의 테크닉이 사용되었다.

  1. 탐색 전에 하루마다 group 배열의 값들을 -1로 초기화하여 미방문 처리해준다.

  2. 리스트를 이용하여 탐색된 나라들을 저장하여 탐색이 끝난 후 인구 이동을 처리한다.

  3. 인구이동이 끝나면 모든 나라의 국경이 닫히므로 groupCnt 값이 N*N까지 올라간다. 이를 탐색의 종료 조건으로 하여 while문을 빠져나온다.

다른 풀이

import java.util.*;

public class Main {
	public static int N, L, R;
	public static int day = 0;
	public static int[][] map;
	public static int[][] check;
	public static int[] dy = {1, 0, -1, 0};
	public static int[] dx = {0, 1, 0, -1};

	public static void bfs(int y, int x) {
		ArrayList<Point> list = new ArrayList<>();
		Queue<Point> q = new LinkedList<>();
		q.add(new Point(y, x));
		check[y][x] = 1;
		int sum = map[y][x];
		int cnt = 1;
		list.add(new Point(y, x));

		while (!q.isEmpty()) {
			Point p = q.poll();
			for (int i = 0; i < 4; i++) {
				int ny = p.y + dy[i];
				int nx = p.x + dx[i];
				if (ny < 0 || ny >= N || nx < 0 || nx >= N) continue;
				if(check[ny][nx] == 0) {
					int dif = Math.abs(map[ny][nx] - map[p.y][p.x]);
					if (L <= dif && dif <= R) {
						q.add(new Point(ny, nx));
						check[ny][nx] = 1;
						sum += map[ny][nx];
						cnt++;
						list.add(new Point(ny, nx));
					}
				}
			}
		}

		for (int i = 0; i < list.size(); i++) {
			y = list.get(i).y;
			x = list.get(i).x;
			check[y][x] = sum / cnt;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		L = sc.nextInt();
		R = sc.nextInt();
		map = new int[N][N];
		check = new int[N][N];
        
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				map[i][j] = sc.nextInt();
			}
		}

		while (true) {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					if (check[i][j] == 0) {
						bfs(i, j);
					}
				}
			}
			if(compareMap()) break;
			else day++;
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					map[i][j] = check[i][j];
					check[i][j] = 0;
				}
			}
		}
		System.out.println(day);
	}
	
	static boolean compareMap() {
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				if(map[i][j] != check[i][j]) return false;
			}
		}
		return true;
	}

	static class Point {
		public int y, x;
		
		public Point(int y, int x) {
			this.y = y;
			this.x = x;
		}
	}
}

인구 이동 일어나기 전 인구가 map 배열이고 인구 이동이 일어난 후에 인구가 check 배열이 된다.



BFS Share