0. A칸에서 이동해 B칸으로 갈 경우, A와 B는 같은 집합에 속한다
- 이러한 이동-집합에 대해, 각 집합당 1개의 SAFE-ZONE이 필요하게 된다
- disjoint-set으로 집합 관리
1. n*m개의 각 칸을 set으로 만들고, set의 갯수 또한 n*m으로 초기화한다
2. 모든 칸을 순회하며 각 칸의 이동에 따라 도착지점의 set과 결합한다
3. 최종적으로 남아있는 set의 갯수가 필요한 SAFE-ZONE의 수가 된다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
n = pint(st.nextToken());
m = pint(st.nextToken());
init();
for (int i = 0; i < n; i++) {
String s =br.readLine();
for (int j = 0; j < m; j++) {
switch(s.charAt(j)) {
case 'U':
union(i*m+j, (i-1)*m+j);
break;
case 'D':
union(i*m+j, (i+1)*m+j);
break;
case 'L':
union(i*m+j, i*m+j-1);
break;
case 'R':
union(i*m+j, i*m+j+1);
break;
default:
break;
}
}
}
System.out.println(cntSet);
}
static int n,m;
static int[][]parent;
static int cntSet;
static void init() {
parent = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
parent[i][j]=m*i+j;
}
}
cntSet=n*m;
}
static int find(int x) {
if(parent[x/m][x%m]!=x)return parent[x/m][x%m]=find(parent[x/m][x%m]);
return x;
}
static void union(int x, int y) {
int rx = find(x), ry=find(y);
if(rx!=ry) {
parent[rx/m][rx%m]=ry;
cntSet--;
}
}
static int pint(String s) {
return Integer.parseInt(s);
}
}
'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글
[백준] 13549 - 숨바꼭질 3 (0) | 2021.05.29 |
---|---|
[백준] 12851 - 숨바꼭질 2 (0) | 2021.05.29 |
[백준] 10942 - 팰린드롬? (0) | 2021.05.19 |
[백준] 1068 - 트리 (0) | 2021.05.14 |
[백준] 16946 - 벽 부수고 이동하기 4 (0) | 2021.05.13 |
[백준] 20040 - 사이클 게임 (0) | 2021.05.05 |
[백준] 1062 - 가르침 (0) | 2021.05.05 |