나의 풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int r, c;
static char arr[][];
static int pipe;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine());
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
arr = new char[r][c];
for (int i = 0; i < r; i++) {
arr[i] = br.readLine().toCharArray();
}
for (int i = 0; i < r; i++) {
if (dfs(i, 0)) {
pipe++;
}
}
System.out.println(pipe);
}
static boolean dfs(int row, int col) {
arr[row][col] = 'o'; // 방문 표시
if (col == c - 1) { // 마지막 열에 도착한 것
return true;
}
if (row > 0 && arr[row - 1][col + 1] == '.') {// 오른쪽위대각선
if (dfs(row - 1, col + 1))
return true;
}
if (arr[row][col + 1] == '.') {// 오른쪽
if (dfs(row, col + 1))
return true;
}
if (row + 1 < r && arr[row + 1][col + 1] == '.') {// 대각선 아래
if (dfs(row + 1, col + 1))
return true;
}
return false;
}
}
* 각 칸은 오른쪽, 오른쪽 위 대각선, 오른쪽 아래 대각선으로 연결할 수 있다.
따라서 i행 0열부터 시작하여 오른쪽, 오른쪽 위 대각선, 오른쪽 아래 대각선으로 가는 3가지 경우를 DFS로 탐색한다.
1) 기저조건
마지막 열에 도착했다면 0~마지막열까지 파이프라인을 모두 설치했음을 뜻하므로 true 를 리턴하며 종료한다.
2) 방문표시
dfs 문을 돌면서 현재 row, col 에 방문표시를 한다.
처음에는 만약 DFS 로 마지막 열까지 도달하지 못한 경우에는 다시 방문 표시를 원상복귀해야하는 것 아닌가? 하고 생각했다.
그러나 다시 생각해본다면, 하지 않아야 함을 알 수 있다.
왜냐하면 DFS 에 성공한 경우, 실패한 경우 모두 다시 탐색할 필요가 없기 때문이다!!!!!
1) 만약 DFS에 성공한 경우 => 이미 다른 파이프가 설치된 경우이므로 방문 표시 필요
2) 만약 DFS에 실패한 경우 => 다른 case에서 해당 row,col 에서 DFS 탐색을 진행할 경우 실패함을 뜻한다. 따라서 다른 경우에서 실패가 보장된 좌표를 다시 탐색하지 않도록 하는 것이다.
3) 탐색
오른쪽 위 대각선 -> 오른쪽 -> 오른쪽 아래 대각선 순서대로 탐색해야 한다. 왜냐하면 최대한 많은 파이프라인을 연결해야 하므로, 파이프가 밑 행으로 내려오는 것 보다 위에 존재해야 더 많은 공간이 확보되기 때문이다.
즉, 만약 오른쪽 위 대각선에서 마지막 열까지 도달할 수 있다면, 오른쪽과 오른쪽아래대각선은 굳이 탐색하지 않아도 이미 최적의 해가 구해졌음을 뜻하는 것이다.
=> 따라서 아래와 같이 dfs() 문이 true 를 리턴하는 경우에는 return true 를 하여, 가지치기를 방지해야 한다.
'알고리즘 > DFS, BFS' 카테고리의 다른 글
[백준] 1600번: 말이 되고픈 원숭이 - java (0) | 2023.02.24 |
---|---|
[백준] 6987번: 월드컵 - java (0) | 2023.02.21 |
[백준] 14752번: 개미굴 - java (0) | 2023.02.19 |
[백준] 1941번: 소문난 칠공주 - java (0) | 2023.02.19 |
[백준] 15683번: 감시 - java (0) | 2023.02.19 |
댓글