본문 바로가기

알고리즘/문제풀이

[백준] 17070. 파이프 옮기기1

반응형

https://www.acmicpc.net/problem/17070

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의 번호이고, 행과 열의 번호는 1부터 시작한다. 각각의 칸은 빈 칸이거나 벽이다. 오늘은 집 수리를 위해서 파이프 하나를 옮기려고 한다. 파이프는 아래와 같은 형태이고, 2개의 연속된 칸을 차지하는 크기이다. 파이프는 회전시킬 수 있으며, 아래와 같이

www.acmicpc.net


파이프가 차지하는 크기는 2칸이지만, 실질적으로 움직이는 파이프는 오른쪽 한칸이기 때문에 시작 좌표를 (0, 1)에서 설정하여 움직일 수 있는 모든 방향을 재귀적으로 호출하여 (N, N) 칸으로 이동하면 되는 문제입니다.

제가 처음에 풀고 틀렸던 부분은 오른쪽으로 움직이거나 아래로 움직일 때에는 움직이는 그 부분에 벽이 있는지 없는지 검사하면 되는데, 대각선으로 움직일 때 대각선방향만이 아닌 오른쪽과 아래쪽도 보면서 세 방향을 검사해야 된다는 것입니다.


import java.util.Scanner;

public class Main {
	
	static int N, answer;
	static int[][] map;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		map = new int[N][N];
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				map[i][j] = sc.nextInt();
			}
		}
		
		recur(0,1,0);
		// d -> 0 : 가로, 1 : 세로, 2 : 대각선
		
		System.out.println(answer);
	}
	
	public static void recur(int x, int y, int d) {
		
		if(x == N-1 && y == N-1 && map[x][y] != 1) {
			answer++;
			return;
		}
		
		// 현재 놓여있는 막대가 가로일 때
		if(d == 0) {
			// 오른쪽으로 한칸 움직이기
			if(isInside(x, y+1) && map[x][y+1] == 0) {
				recur(x, y+1, 0);
			}
			
			// 오른쪽 아래 대각선으로 움직이기
			if(isInside(x+1, y+1) && map[x+1][y+1] == 0 && map[x+1][y] == 0 && map[x][y+1] == 0) {
				recur(x+1, y+1, 2); 
			}
			
		} else if(d == 1) { // 막대가 세로 일 때
			// 밑으로 움직이기
			if(isInside(x+1, y) && map[x+1][y] == 0) {
				recur(x+1, y, 1);
			}
			
			// 오른쪽 아래로 움직이기
			if(isInside(x+1, y+1) && map[x+1][y+1] == 0 && map[x][y+1] == 0 && map[x+1][y] == 0) {
				recur(x+1, y+1, 2);
			}
			
		} else if(d == 2) {	// 막대가 대각선일 때
			// 가로로 움직이기
			if(isInside(x, y+1) && map[x][y+1] == 0) {
				recur(x, y+1, 0);
			}
			
			// 세로로 움직이기
			if(isInside(x+1, y) && map[x+1][y] == 0) {
				recur(x+1,y, 1);
			}
			
			// 대각선으로 움직이기
			if(isInside(x+1, y+1) && map[x+1][y+1] == 0 && map[x][y+1] == 0 && map[x+1][y] == 0) {
				recur(x+1,y+1,2);
			}	
		}
	}
	
	public static boolean isInside(int x, int y) {
		return x>=0 && x<N && y>=0 && y<N;
	}
	
}
반응형

'알고리즘 > 문제풀이' 카테고리의 다른 글

[백준] 17135. 캐슬 디펜스  (0) 2020.02.19
[백준] 3109. 빵집  (0) 2020.02.19
[SWEA] 1873. 상호의 배틀필드  (4) 2020.02.10
[SWEA] 1861. 정사각형 방  (0) 2020.02.10
[백준] 4179. 불!  (0) 2020.02.05