알고리즘 공부

[백준 3109번] 빵집 - java

철매존 2024. 10. 13. 20:38
728x90

문제 설명

1. R*C 격자가 주어지고, '.'은 갈 수 있는 길 'X' 는 갈 수 없는길(건물) 이다.

2. 왼쪽 끝에서부터 시작해서 오른쪽 끝으로 연결이 가능하면 파이프가 이어지는것.

3. 하나의 시작점에서는 하나만 도달한다.

4. 이미 연결되면 그 다음에는 연결되지 않는다.

5. 그래서 도달한게 몇개인지 맞추면 된다.

 

풀이 과정

 1. DFS, 그리디이다.

 2. 백트래킹도 가능할 것 같기는 한데... 나는 DFS로 풀었고 그 이유는

 3. 위에서부터 아래로 가면서, 그리고 위로 가면서 확인하면 결국 갈 수 있는 길 자체가 정해진다.(그리디의 일종?)

 4. 즉, 위에서부터 확인하고 올라가기 - 직선 - 내려가기 할 때에 위에서 이미 갔으면 그거 자체가 하나의 루트가 된다. 즉 아래에서 이거때문에 못간다고 해도 달라질게 없다.

 5. 그래서 위에서부터 내려가면서 DFS + 그리디 하면 쉽게 풀 수 있는 문제이다.

 

코드

 

import java.util.*;

public class Main {
    private static int[] xMove = {1, 1, 1};
    private static int[] yMove = {-1, 0, 1};
    
    private static boolean map[][]; 
    private static int ans = 0;

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        
        int R = sc.nextInt();
        int C = sc.nextInt();
        sc.nextLine(); // 개행을 위해 넣는다.
        
        map = new boolean[R][C];
        
        // 간단하게 장애물 유무를 true/false로 넣는다.
        // true면 뭔가 장애물이 있는겨.
        for(int i=0; i<R; i++) {
          String input = sc.nextLine();
          for(int j=0; j<C; j++) {
            char index = input.charAt(j);
            if (index == '.') {
              map[i][j] = false;
            } else {
              map[i][j] = true;
            }
          }
        }
        
        // 위에서부터 DFS 시작
        for(int i=0; i<R; i++) {
          dfs(0, i);
        }
        
        System.out.println(ans);
    }
    
    private static boolean dfs(int x, int y) {
      for (int i=0; i<3; i++) {
        int xTo = x + xMove[i]; // 얘는 어차피 앞으로만 간다.
        int yTo = y + yMove[i]; // 지금보다 위/직선/아래로 이동한다.
        	// 박스 내에서 움직이기
    		if(xTo<0 || xTo>=map[0].length || yTo<0 || yTo>=map.length) continue;
    		
            // 그래서 그쪽으로 갔을 때에
            // 장애물이 없는 길이라면
    		if(!map[yTo][xTo]) {
              // 이게 목적지라면?
    		  if(xTo == map[0].length - 1) {
    		    ans++; // 답이고
    		    return true; // 이 길이 정답이라고 하고, 더이상의 DFS는 없다.
    		  }
    		  
              // 이길은 지나감(즉 장애물이 된다.)
              // 참고로 이거 다 해줘도 되는 이유는 어차피 여기서 못가면 다른곳에서도 못가기 떄문
              // 여기서 가면 다른곳에서 못가기도 하고
    		  map[yTo][xTo] = true;
    		  if(dfs(xTo, yTo)) return true; // DFS결과 정답이면 정답 루트 색칠
    		}
      }
  		
  		return false;
    }
}