알고리즘 문제 풀이/BOJ 골드
[백준] 16724 - 피리 부는 사나이
natonato
2021. 5. 16. 17:22
16724번: 피리 부는 사나이
첫 번째 줄에 지도의 행의 수를 나타내는 N(1 ≤ N ≤ 1,000)과 지도의 열의 수를 나타내는 M(1 ≤ M ≤ 1,000)이 주어진다. 두 번째 줄부터 N개의 줄에 지도의 정보를 나타내는 길이가 M인 문자열이 주
www.acmicpc.net
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);
}
}