N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다.
오늘부터 인구 이동이 시작되는 날이다.
인구 이동은 하루 동안 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다.
각 나라의 인구수가 주어졌을 때, 인구 이동이 며칠 동안 발생하는지 구하는 프로그램을 작성하시오.
첫째 줄에 N, L, R이 주어진다. (1 ≤ N ≤ 50, 1 ≤ L ≤ R ≤ 100)
둘째 줄부터 N개의 줄에 각 나라의 인구수가 주어진다. r행 c열에 주어지는 정수는 A[r][c]의 값이다. (0 ≤ A[r][c] ≤ 100)
인구 이동이 발생하는 일수가 2,000번 보다 작거나 같은 입력만 주어진다.
인구 이동이 며칠 동안 발생하는지 첫째 줄에 출력한다.
2 20 50
50 30
20 40
1
4 10 50
10 100 20 90
80 100 60 70
70 20 30 40
50 20 100 10
3
import java.util.*;
public class 인구이동_16234 {
//방문한 국가인지 확인
static boolean[][] visit;
//땅 크기, 인구 제한 사항
static int n,l,r;
//인구이동하는 국가 정보
static ArrayList<Pos> list;
//인구수
static int[][] population;
public static void main(String[] args) {
Scanner sc = new Scanner (System.in);
n = sc.nextInt();
l = sc.nextInt();
r = sc.nextInt();
//인구 수
population = new int[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
population[i][j] = sc.nextInt();
}
}
int result = 0;
//인구 이동이 없을 때까지 반복
while(true){
visit = new boolean[n][n];
boolean move = false;
for(int i=0; i<n ; i++){
for( int j=0; j<n; j++){
if(!visit[i][j]) {
if(bfs(i,j)) move = true; //이동가능한 국경이 있는지 확인
}
}
}
if(!move) break;
result ++;
}
System.out.println(result);
}
static boolean bfs(int x, int y){
//이동가능한 나라 리스트
list = new ArrayList<Pos>();
Queue<Pos> queue = new LinkedList<>();
list.add(new Pos(x,y));
queue.add(new Pos(x,y));
visit[x][y] = true;
int total = population[x][y];
int[] dx = {1,-1,0,0};
int[] dy = {0,0,1,-1};
while(!queue.isEmpty()){
Pos pos = queue.poll();
x = pos.x;
y = pos.y;
for(int i=0; i<4;i++){
int nx = x +dx[i];
int ny = y+ dy[i];
if(nx>=0 && nx<n && ny>=0 && ny<n && !visit[nx][ny]){
int populationDifference = Math.abs(population[nx][ny]- population[x][y]);
//이동할 국가의 인구 수 차이가 l보다 크고 r보다 작은지 확인
if(populationDifference >= l && populationDifference<=r){
total += population[nx][ny];
queue.add(new Pos(nx,ny));
list.add(new Pos(nx,ny));
visit[nx][ny] = true;
}
}
}
}
if(list.size() > 1) {
int movingNum = total/list.size();
//인구 수 변경
for(Pos pos : list){
int changeX = pos.x;
int changeY = pos.y;
population[changeX][changeY] = movingNum;
}
//인구이동이 가능
return true;
}
//인구 인동 불가능
return false;
}
static class Pos{
int x;
int y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
}
}
너비 우선 탐색, 그래프 이론, 그래프 탐색, 구현, 시뮬레이션