코드굽는 타자기

Baekjoon[17070] - 파이프 옮기기 1 본문

알고리즘/완전탐색

Baekjoon[17070] - 파이프 옮기기 1

bright-jun 2020. 2. 2. 00:07

링크

Baekjoon[17070]

문제설명

  • 격자 이동 경우의 수 와 비슷함. 대신 이동 규칙이 다름.

문제풀이

  • 하라는대로 모든 경우의 수를 구한다. simulation+탐색

문제코드

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main17070 {
    static int Ans=0;
    static int[][] dir = {    //우, 우하, 하
            {0,1},
            {1,1},
            {1,0}
    };

    public static void Move(int[][] map, int r, int c, int b_dir) {
        int N = map.length;
        if(r==N-1 && c==N-1) {    //끝까지 이동한 경우
            Ans++;
            return;
        }

        int nr = 0;
        int nc = 0;

        if(b_dir==0) {    //우 -> 우, 우하
            for (int i = 0; i < 2; i++) {
                nr = r + dir[i][0]; 
                nc = c + dir[i][1];

                if(nr>=0 && nr<N && nc>=0 && nc<N) {    //맵 안에서 이동할 때
                    if(map[nr][nc]==0) {    //제대로 파이프 이동함
                        if(i==1) {
                            if(map[nr-1][nc]==0 && map[nr][nc-1]==0) {
                                Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                            }
                            else continue;
                        }
                        else{
                            Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                        }
                    }
                    else {    //벽 만남
                        continue;
                    }
                }
                else {    //맵 밖으로 나가는 경우
                    continue;
                }
            }
        }
        else if(b_dir==1) {    //우하 -> 우, 우하, 우
            for (int i = 0; i < 3; i++) {
                nr = r + dir[i][0]; 
                nc = c + dir[i][1]; 

                if(nr>=0 && nr<N && nc>=0 && nc<N) {    //맵 안에서 이동할 때
                    if(map[nr][nc]==0) {    //제대로 파이프 이동함
                        if(i==1) {
                            if(map[nr-1][nc]==0 && map[nr][nc-1]==0) {
                                Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                            }
                            else continue;
                        }
                        else{
                            Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                        }
                    }
                    else {    //벽 만남
                        continue;
                    }
                }
                else {    //맵 밖으로 나가는 경우
                    continue;
                }
            }
        }
        else {    //하 -> 우하, 하
            for (int i = 1; i < 3; i++) {
                nr = r + dir[i][0]; 
                nc = c + dir[i][1]; 

                if(nr>=0 && nr<N && nc>=0 && nc<N) {    //맵 안에서 이동할 때
                    if(map[nr][nc]==0) {    //제대로 파이프 이동함
                        if(i==1) {
                            if(map[nr-1][nc]==0 && map[nr][nc-1]==0) {
                                Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                            }
                            else continue;
                        }
                        else{
                            Move(map,nr,nc,i);    //위치, 방향 기억 후 또 이동
                        }
                    }
                    else {    //벽 만남
                        continue;
                    }
                }
                else {    //맵 밖으로 나가는 경우
                    continue;
                }
            }
        }
        return;    //이동할 수 없을 경우
    }

    public static void main(String[] args) throws FileNotFoundException {
        System.setIn(new FileInputStream("res/baekjoon/17070.txt"));
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[][] map = new int[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                map[i][j]=sc.nextInt();
            }
        }
        Move(map,0,1,0);
        System.out.println(Ans);
        /*
         * 초기화
         */
        Ans=0;
    }
}

아쉬운점

  • 맵 탐색하다가 return, continue 고민함
    • return 하면 한 지점에서 0,1,2 방향으로 탐색 할 때 0에서 return시, 1,2방향 탐색 안함
    • continue로 해야 완전탐색 가능
  • 대각선 이동할 때는 3칸 고려해야하는 제약사항 고려안했었음.
  • 이동할 수 없을 경우 0 return 고려안했음
    • void 함수를 사용했어서 return 안적었어도 테케 통과됐던것 같음.

잘한점

  • 처음에는 격자이동 경우의 수 처럼 공식 이용해서 계산하려다가 그냥 귀찮아서 컴퓨터를 믿고 구하기로 했음.
  • 경계검사, 벽검사 잘했음
  • 1시간안에 품
Comments