알고리즘/문제풀이

[BFS] 인구이동

lipnus 2019. 4. 10. 20:13
반응형

백준 16234 인구이동 (삼성 SW역량테스트 기출)

https://www.acmicpc.net/problem/16234


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

static int N;
static int L;
static int R;

static int[] dn = {-1, 0, 1, 0};
static int[] dm = {0, 1, 0, -1};

static int[][] map;
static int[][] visited;

static int count=0; //인구이동 횟수

public static void main(String[] args) throws Exception{

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());

map = new int[N+1][N+1];
visited = new int[N+1][N+1];

for(int i=1; i<=N; i++){
st = new StringTokenizer(br.readLine());
for(int j=1; j<=N; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}


// printAllDoor();

loop();
System.out.println(count);

}

static void loop(){

boolean moved = false;
for(int i=1; i<=N; i++){
for(int j=1; j<=N; j++){

if(visited[i][j]==0 && bfs(new Position(i,j)) ){
moved=true;
}
}
}

if(moved==true){
count++;
reset();
loop();
}else{
return;
}

}



static boolean bfs(Position sP){

int tSum = 0;
Queue<Position> team = new LinkedList<>(); //같은편끼리 여기 넣는다
Queue<Position> q = new LinkedList<>(); //bfs탐색에 필요한 큐

q.add(sP);
visited[sP.n][sP.m] = 1;
team.add(sP);
tSum += map[sP.n][sP.m];

while (!q.isEmpty()){

Position pos = q.poll();

//4방향 탐색
for(int i=0; i<4; i++){

Position nPos = new Position(pos.n + dn[i], pos.m + dm[i]);

if(isIn(nPos) && visited[nPos.n][nPos.m]==0 && isOpen(pos, nPos) ){
visited[nPos.n][nPos.m]=1;
q.add(nPos);

team.add(nPos);
tSum += map[nPos.n][nPos.m];
}
}
}
return sharePeople(team, tSum);
}


//같은팀끼리 나눠가진다
static boolean sharePeople(Queue<Position> team, int tSum){

int tSize = team.size();
int nPeople = tSum/tSize;

boolean moved = false;

for(Position p: team){
if(map[p.n][p.m] != nPeople){
map[p.n][p.m] = nPeople;
moved = true;
}
}
return moved;
}




//이동가능한지 확인
static boolean isOpen(Position p1, Position p2){
int diff = Math.abs( map[p1.n][p1.m] - map[p2.n][p2.m] );

if( L <= diff && diff <= R ) return true;
return false;
}


//범위 안이냐
static boolean isIn(Position p){
if(p.n<1 || N<p.n || p.m<1 || N<p.m) return false;
return true;
}


static void reset(){
for(int i=1; i<=N; i++){
for(int j=1; j<=N; j++){
visited[i][j] = 0;
}
}
}


static class Position{
int n;
int m;

Position(int n, int m){
this.n = n;
this.m = m;
}
}
}


반응형

'알고리즘 > 문제풀이' 카테고리의 다른 글

[DP] 퇴사  (0) 2019.04.11
[다익스트라] 최단거리  (0) 2019.04.10
[DFS] 치킨배달(2번째)  (0) 2019.04.09
[시뮬레이션] 큐빙  (0) 2019.04.08
[시뮬레이션] 드래곤 커브  (0) 2019.04.07