알고리즘
백준 16724번 피리 부는 사나이 (JAVA)
박카스마시며코딩
2022. 7. 23. 17:41
https://www.acmicpc.net/problem/16724
16724번: 피리 부는 사나이
첫 번째 줄에 지도의 행의 수를 나타내는 N(1 ≤ N ≤ 1,000)과 지도의 열의 수를 나타내는 M(1 ≤ M ≤ 1,000)이 주어진다. 두 번째 줄부터 N개의 줄에 지도의 정보를 나타내는 길이가 M인 문자열이 주
www.acmicpc.net
저는 DFS를 통해 해당 문제를 해결하였습니다.
저는 visited배열을 숫자로 저장하였습니다.
현재 숫자와 같은지 다른지 즉, 같은 사이클에 있는지 아닌지에 따라 다르게 처리하였습니다.
같은 숫자 즉, 같은 사이클이라면 true를 리턴하여 이때 결과값(SAFE_ZONE)의 개수를 늘렸습니다.
다르다면 false를 리턴하여 이때는 결과값을 늘리지 않았습니다.
package BOJ.dfs;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_16724 {
private static final String DIR = "URDL";
private static final int NOT_VISITED = 0;
private static final int[] DY = {-1,0,1,0};
private static final int[] DX = {0,1,0,-1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
int m = stoi.apply(st.nextToken());
char[][] map = new char[n][m];
for(int i = 0 ; i < n ; i++){
String command = br.readLine();
for(int j = 0 ; j < m ; j++){
map[i][j] = command.charAt(j);
}
}
int result = 0;
int num = 1;
int[][] visited = new int[n][m];
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
if(visited[i][j] == NOT_VISITED && dfs(i,j,map,n,m,visited,num++)){
result++;
}
}
}
System.out.println(result);
}
private static boolean dfs(int y, int x,char[][] map,int n, int m,int[][] visited, int num){
visited[y][x] = num;
int dir = DIR.indexOf(map[y][x]);
int ny = y + DY[dir];
int nx = x + DX[dir];
if(visited[ny][nx] == NOT_VISITED){
return dfs(ny,nx,map,n,m,visited,num);
}else if(visited[ny][nx] == num){
return true;
}
return false;
}
private static boolean checkBound(int y, int x, int n, int m){
if(y >= 0 && y < n && x >= 0 && x < m){
return true;
}
return false;
}
}