알고리즘/문제풀이
[백준] 17070. 파이프 옮기기1
BSHwan
2020. 2. 19. 22:40
반응형
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;
}
}
반응형