17070

백준 17070번

Link: 17070번: 파이프 옮기기 1


문제 설명

오늘도 BFS 문제다.

전형적인 BFS와는 다른 방식으로 풀어야 하는 문제였다.

보통 BFS의 경우 1 * 1짜리 한칸만 고려해줘도 풀리는 문제들이 대다수인데 이 문제같은 경우 파이프의 앞, 뒤를 함께 고려해야 한다는 점이 큰 차이점이었다.

이외에도 회전하는 조건이 꽤 까다롭다는 점이 차이점이었으며 반복 방문을 막기 위해 BFS에서 보통 사용하는 visit 배열을 쓰지 않아야 풀리는 문제라는 점도 차이점이다.

그리고 이 문제의 경우 BFS로 풀면 88%에서 시간초과가 난다.

혹시나 해서 DFS로 바꿔서 풀어보니 바로 풀렸다.

DFS는 재귀호출이기 때문에 함수 호출에 걸리는 시간도 있으니 BFS보다 더 오래 걸릴것이라고 생각했는데 잘못 생각했던것 같다.

조건이 꽤 많은데 이 조건들을 하나하나 반영하며 DFS로 풀면 바로 풀리는 문제였다.


정답 코드

package Baekjoon;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_17070 {
    static class Pipe{
        int frontX, frontY;

        int direction;

        public Pipe(int frontX, int frontY, int direction) {
            this.frontX = frontX;
            this.frontY = frontY;
            this.direction = direction;
        }
    }

    static int[] dx = {0, 1, 1};
    static int[] dy = {1, 1, 0};
    static int[][] map;
    static int N;
    static int count;

    public static void DFS(Pipe start) {
        int currentFrontX = start.frontX;
        int currentFrontY = start.frontY;
        int currentDirection = start.direction;

        if(currentFrontX == N && currentFrontY == N) {
            count++;
            return;
        }

        for(int i=0; i<3; i++) {
            int nextFrontX = currentFrontX + dx[i];
            int nextFrontY = currentFrontY + dy[i];
            int nextDirection = i;

            if((currentDirection == 0 && nextDirection == 2) || (currentDirection == 2 && nextDirection == 0)) {
                continue;
            }

            if(i == 1) {
                if(nextFrontX <= N && nextFrontY <= N) {
                    if(map[nextFrontX][nextFrontY] == 0 && map[currentFrontX][currentFrontY] == 0 && map[nextFrontX][nextFrontY - 1] == 0 && map[currentFrontX][currentFrontY + 1] == 0) {
                        DFS(new Pipe(nextFrontX, nextFrontY, nextDirection));
                    }
                }
            }
            else {
                if(nextFrontX <= N && nextFrontY <= N) {
                    if(map[nextFrontX][nextFrontY] == 0 && map[currentFrontX][currentFrontY] == 0) {
                        DFS(new Pipe(nextFrontX, nextFrontY, nextDirection));
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());
        count = 0;

        map = new int[N+1][N+1];

        for(int i=1; i<=N; i++) {
            StringTokenizer row = new StringTokenizer(br.readLine());
            for(int j=1; j<=N; j++) {
                map[i][j] = Integer.parseInt(row.nextToken());
            }
        }

        Pipe start = new Pipe(1, 2, 0);

        DFS(start);

        System.out.println(count);
    }

}