Skip to content

Commit

Permalink
[Gold V] Title: 파이프 옮기기 1, Time: 276 ms, Memory: 15380 KB -BaekjoonHub
Browse files Browse the repository at this point in the history
  • Loading branch information
dukbong committed Feb 21, 2024
1 parent a8830ed commit 47e8f21
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
58 changes: 58 additions & 0 deletions 백준/Gold/17070. 파이프 옮기기 1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# [Gold V] 파이프 옮기기 1 - 17070

[문제 링크](https://www.acmicpc.net/problem/17070)

### 성능 요약

메모리: 15380 KB, 시간: 276 ms

### 분류

다이나믹 프로그래밍, 그래프 이론, 그래프 탐색

### 제출 일자

2024년 2월 21일 15:02:50

### 문제 설명

<p>유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의 번호이고, 행과 열의 번호는 1부터 시작한다. 각각의 칸은 빈 칸이거나 벽이다.</p>

<p>오늘은 집 수리를 위해서 파이프 하나를 옮기려고 한다. 파이프는 아래와 같은 형태이고, 2개의 연속된 칸을 차지하는 크기이다.</p>

<p style="text-align: center;"><img alt="" src="" style="width: 138px; height: 70px;"></p>

<p>파이프는 회전시킬 수 있으며, 아래와 같이 3가지 방향이 가능하다.</p>

<p style="text-align: center;"><img alt="" src="" style="width: 427px; height: 136px;"></p>

<p>파이프는 매우 무겁기 때문에, 유현이는 파이프를 밀어서 이동시키려고 한다. 벽에는 새로운 벽지를 발랐기 때문에, 파이프가 벽을 긁으면 안 된다. 즉, 파이프는 항상 빈 칸만 차지해야 한다.</p>

<p>파이프를 밀 수 있는 방향은 총 3가지가 있으며, →, ↘, ↓ 방향이다. 파이프는 밀면서 회전시킬 수 있다. 회전은 45도만 회전시킬 수 있으며, 미는 방향은 오른쪽, 아래, 또는 오른쪽 아래 대각선 방향이어야 한다.</p>

<p>파이프가 가로로 놓여진 경우에 가능한 이동 방법은 총 2가지, 세로로 놓여진 경우에는 2가지, 대각선 방향으로 놓여진 경우에는 3가지가 있다.</p>

<p>아래 그림은 파이프가 놓여진 방향에 따라서 이동할 수 있는 방법을 모두 나타낸 것이고, 꼭 빈 칸이어야 하는 곳은 색으로 표시되어져 있다.</p>

<p style="text-align: center;"><img alt="" src="" style="width: 578px; height: 203px;"></p>

<p style="text-align: center;">가로</p>

<p style="text-align: center;"><img alt="" src="" style="width: 579px; height: 203px;"></p>

<p style="text-align: center;">세로</p>

<p style="text-align: center;"><img alt="" src="" style="width: 886px; height: 203px;"></p>

<p style="text-align: center;">대각선</p>

<p>가장 처음에 파이프는 (1, 1)와 (1, 2)를 차지하고 있고, 방향은 가로이다. 파이프의 한쪽 끝을 (N, N)로 이동시키는 방법의 개수를 구해보자.</p>

### 입력

<p>첫째 줄에 집의 크기 N(3 ≤ N ≤ 16)이 주어진다. 둘째 줄부터 N개의 줄에는 집의 상태가 주어진다. 빈 칸은 0, 벽은 1로 주어진다. (1, 1)과 (1, 2)는 항상 빈 칸이다.</p>

### 출력

<p>첫째 줄에 파이프의 한쪽 끝을 (N, N)으로 이동시키는 방법의 수를 출력한다. 이동시킬 수 없는 경우에는 0을 출력한다. 방법의 수는 항상 1,000,000보다 작거나 같다.</p>

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {

int size, result = 0;
int arr[][];
int moveX[] = { 1, 0, 1 };
int moveY[] = { 0, 1, 1 };

public static void main(String[] args) throws Exception {
new Main().solution();
}

public void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
size = Integer.parseInt(br.readLine());
arr = new int[size][size];
for (int i = 0; i < size; i++) {
arr[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
}
solve(1, 0, 0);
System.out.println(result);
}

// 0 가로 1 세로 2 대각
private void solve(int x, int y, int shape) {
if (x == size - 1 && y == size - 1) {
result++;
return;
}
for (int d = 0; d < 3; d++) {
int newY = y + moveY[d];
int newX = x + moveX[d];

if (newY >= size || newX >= size || arr[newY][newX] == 1)
continue;

if ((d == 1 && shape == 0) || (d == 0 && shape == 1))
continue;

if (d == 2 && (arr[y][x + 1] == 1 || arr[y + 1][x] == 1))
continue;

solve(newX, newY, d);
}
}

}

0 comments on commit 47e8f21

Please sign in to comment.