알고리즘/그래프
[BOJ] 백준 17070 - 파이프 옮기기 풀이
송승현(SSH)
2023. 3. 12. 22:54
1. 문제
https://www.acmicpc.net/problem/17070
17070번: 파이프 옮기기 1
유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의
www.acmicpc.net
2. 풀이 Point
- 파이프의 상태에 따라 움직일 수 있는 경우가 다르기 때문에 이를 분기점으로 나눠주는 것이 중요
- 파이프의 상태에 따라 switch case로 나누어 주었고 파이프의 상태에 따라 갈 수 있는 경우를 재귀 함수를 통해 탐색
- 반복적으로 나오는 경우가 많으므로 이동하는 건 함수로 처리
- 뒤로 돌아오거나 갔던 곳을 다시 가는 경우는 없기에 visited 배열은 필요 없음.
3. 소스코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static int result = 0;
static int N;
static int[][] map;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
map = new int[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
pipeDFS(0, 1, 1); // dir : 1=가로, 2= 세로, 3=대각선
bw.write(Integer.toString(result));
bw.flush();
bw.close();
br.close();
}
private static void pipeDFS(int x, int y, int dir) {
// 끝에 도달할 수 있다면
if (x == N - 1 && y == N - 1 && map[x][y] == 0) {
result += 1;
return;
}
switch (dir) {
case 1:
// 가로는 (1)가로, (2)대각선으로 움직임
// (1) 가로
width(x, y);
// (2) 대각선
diagonal(x, y);
break;
case 2:
// 세로는 (1)세로, (2)대각선으로 움직임
// (1)세로
height(x, y);
// (2)대각선
diagonal(x, y);
break;
case 3:
// 대각선은 (1)가로, (2)세로, (3)대각선으로 움직임
// (1) 가로
width(x, y);
// (2)세로
height(x, y);
// (3) 대각선
diagonal(x, y);
break;
}
}
// 범위를 벗어나는지 확인
private static boolean isSafe(int x, int y) {
if (x >= 0 && x < N && y >= 0 && y < N) {
return true;
}
return false;
}
// 가로 움직임
private static void width(int x, int y) {
if (isSafe(x, y + 1) && map[x][y + 1] == 0) {
pipeDFS(x, y + 1, 1);
}
}
// 세로 움직임
private static void height(int x, int y) {
if (isSafe(x + 1, y) && map[x + 1][y] == 0) {
pipeDFS(x + 1, y, 2);
}
}
// 대각선 움직임
private static void diagonal(int x, int y) {
if (isSafe(x + 1, y + 1) && map[x][y + 1] == 0 && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0) {
pipeDFS(x + 1, y + 1, 3);
}
}
}
4. 점수
85/100