[프로그래머스] Level4 - 지형 이동

 
by 박신종

> 문제

문제 : [지형이동]



> 문제풀이

BFS + Kruskal 사용.

height로 구역을 index로 번호매김하여 구분해주었고(BFS), height보다 큰 경계선을 PriorityQueue에 경계값 오름차순으로 넣어주었다(Kruskal).

소스는 다음과 같다.

package level4;
import java.util.*;
public class Solution_지형이동 {
	static class Pos{
        int x,y;
        Pos(int x, int y){
            this.x = x;
            this.y = y;
        }
    }
    
    static class Edge{
        Pos a,b;
        int value;
        Edge(Pos a, Pos b, int value){
            this.a = a;
            this.b = b;
            this.value = value;
        }
    }
    
    static boolean check(int x, int y, int[][] map){
        if(x>=0 && y>=0 && x<map.length && y<map[x].length){
            return true;
        }else return false;
    }
	static int[][] dir = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
    static public int solution(int[][] land, int height) {
        int answer = 0;
        int[][] group = new int[land.length][land[0].length];
        Queue<Pos> qu = new LinkedList<>();
        int dx,dy;
        int index = 0;
        Queue<Edge> pq = new PriorityQueue<>(new Comparator<Edge>(){
            @Override
            public int compare(Edge o1, Edge o2){
                return o1.value - o2.value;
            }
        });
        
        for(int i=0; i<land.length; i++){
            for(int j=0; j<land[i].length; j++){
                if(group[i][j] == 0){
                    index ++;
                    group[i][j] = index;
                    qu.add(new Pos(i,j));
                    while(!qu.isEmpty()){
                        Pos p = qu.poll();
                        for(int d=0; d<4; d++){
                            dx = p.x + dir[d][0];
                            dy = p.y + dir[d][1];
                            if(check(dx, dy, land) && group[dx][dy] == 0){
                                Pos np = new Pos(dx,dy);
                                int diff = Math.abs(land[p.x][p.y]-land[dx][dy]);
                                if(diff <= height){
                                    group[dx][dy] = index;
                                    qu.add(new Pos(dx,dy));
                                }else{
                                    pq.add(new Edge(p, np, diff));
                                }
                            }
                        }
                    }
                }
            }
        }
		parent = new int[index + 1];
		for (int i = 1; i < parent.length; i++) {
			parent[i] = i;
		}
		while (!pq.isEmpty()) {
			Edge e = pq.poll();
			int a = group[e.a.x][e.a.y];
			int b = group[e.b.x][e.b.y];
			if (union(a, b))
				answer += e.value;
		}
		return answer;
	}
	static int[] parent;
	static int find(int x) {
		if (parent[x] == x)
			return x;
		return parent[x] = find(parent[x]);
	}
	static boolean union(int a, int b) {
		int ap = find(a);
		int bp = find(b);
		if (ap < bp) {
			parent[bp] = ap;
			return true;
		}else if(ap > bp){
			parent[ap] = bp;
			return true;
		}else return false;
	}
}






문제 출처 : Programmers