구현. dfs . 큐
가장 시간을 많이 보낸 부분:
(1) 0,0 좌표와 0,1의 좌표가 인구이동이 가능하다는 것을 어떻게 나타낼 것인가 ?
-> DFS 를 수행. 다음 좌표와 현재 좌표의 인구 차이를 보고 노드를 이어감.
(2) 인구 이동은 한 번에 처리해야 하는데 어떻게 처리할 것인가?
-> idx에 해당하는 queue 형 배열을 선언해서 각각 인구이동이 가능한 구역마다 좌표를 기억해 두었다가 나중에 for문이 끝나고 한 번에 이동하는 식으로 처리.
-> 처음에 시행착오를 얻은 부분 :
1.3 좌표와 1.2 좌표가 인구 이동이 가능하다는 것을 4차원 배열로
//4차원 배열 선언
boolean canMove[][][][]=new boolean[N][N][N][N]
//1.3과 1.2 좌표는 인구 이동이 가능하다
camMove[1][3][1][2] = true
시도해보려다가 메모리의 낭비와 내가 생각하지 못한 오류가 발생해서 철회 하는 과정에서 시간을 많이 소비함.
import java.util.*;
import java.io.*;
public class Main{
static int people[][];
static boolean visited[][];
static int dy[]= {-1,0,1,0};
static int dx[]= {0,-1,0,1};
static int idx;
static int sum[];
static Queue <Integer[]> index[];
static int L,R;
public static void main(String[] args) throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb=new StringBuilder();
StringTokenizer st;
sum=new int[2500];
index=new LinkedList[2500];
st=new StringTokenizer(br.readLine());
int N=Integer.parseInt(st.nextToken());
L=Integer.parseInt(st.nextToken());
R=Integer.parseInt(st.nextToken());
people=new int[N][N];
for(int i=0;i<people.length;i++) {
st=new StringTokenizer(br.readLine());
for(int j=0;j<people.length;j++) {
people[i][j]=Integer.parseInt(st.nextToken());
}
}
int cnt=0;
while(true) {
idx=0;
sum=new int[2500];
visited=new boolean[N][N];
for(int i=0;i<people.length;i++) {
for(int j=0;j<people.length;j++) {
index[idx]=new LinkedList<>();
//방문했다면 continue
if(visited[i][j]) continue;
dfs(i,j);
//dfs 했는데 탐색한게 없다면 continue
if (index[idx].isEmpty()) continue;
//탐색을 최소 1개 한 것이므로 현재 인구도 포함 시킴
index[idx].add(new Integer[] {i,j});
sum[idx]+=people[i][j];
idx++;
}
}
for(int i=0;i<idx;i++) {
int result=sum[i]/index[i].size();
while(!index[i].isEmpty()) {
Integer temp[]=index[i].poll();
people[temp[0]][temp[1]]=result;
}
}
if(idx==0) break;
cnt++;
}
System.out.println(cnt);
}
public static void dfs(int y,int x) {
visited[y][x]=true;
for(int i=0;i<4;i++) {
int nextY=y+dy[i];
int nextX=x+dx[i];
if(nextY<0||nextX<0||nextY>=people.length||nextX>=people.length) continue;
if(visited[nextY][nextX])
continue;
int diff=Math.abs(people[y][x]-people[nextY][nextX]);
if(!(diff>=L&&diff<=R)) continue;
index[idx].add(new Integer[] {nextY,nextX});
sum[idx]+=people[nextY][nextX];
dfs(nextY,nextX);
}
}
}
최적화 진행 -> 548 ms 의 코드를 첨부함.
3달 전에 못풀었었는데 오늘 결국 풀었다.
하루에 백준 1문제 이상 푸는 것을 목표로 하고있다.
https://solved.ac/profile/anwlro0212