[백준] 32964. 재미있는 파이프 퍼즐 (Java)

서재·2025년 1월 7일

백준 알고리즘 풀이

목록 보기
37/49
post-thumbnail

👨‍💻 문제


✍️ 풀이

I자 형 파이프와 L자 형 파이프를 돌려가며 X끼리 서로 이어질 수 있는지 확인하는 문제이다.

시작

위 아래로 나아갈 수 있는지 판단하기 위해 사용할 변수이다.

상단의 경우 우측으로도, 하단으로도 나아갈 수 있기 때문에 고정적으로 true로,
하단의 경우 L 파이프의 경우만 true로 초기화한다.

    boolean canGoUp = true;
    boolean canGoDown = (pipes[0][1] == 'L');

중간

이제 우측으로 나아가며 탐색한다.
세로가 2칸 뿐이기 때문에 몇 가지 경우의 수만 고려하면 된다.

순서대로
위에서 위로 갈 수 있는 경우,
위에서 아래로 갈 수 있는 경우,
아래에서 아래로 갈 수 있는 경우,
아래에서 위로 갈 수 있는 경우이다.

이를 측정하고 bool 변수를 갱신한다.

        for (int i=1; i<N-1; i++) {
            boolean canGoUpNext = false;
            boolean canGoDownNext = false;
            if (canGoUp) {
                if (pipes[i][0] == 'I'){
                    canGoUpNext = true;
                }
                if (pipes[i][0] == 'L' && pipes[i][1] == 'L') {
                    canGoDownNext = true;
                }
            }
            if (canGoDown) {
                if (pipes[i][1] == 'I'){
                    canGoDownNext = true;
                }
                if (pipes[i][0] == 'L' && pipes[i][1] == 'L') {
                    canGoUpNext = true;
                }
            }
            canGoUp = canGoUpNext;
            canGoDown = canGoDownNext;
        }

마지막

마지막으로 목적지에 도달할 수 있는 방법은 2가지이다.

  • 위로 나아갈 수 있고 위가 L 파이프이다.
  • 아래로 나아갈 수 있다.

둘 중 하나만 만족하면 된다.

        boolean result = (canGoUp && pipes[N-1][0] == 'L' || canGoDown);
        System.out.println(result ? "YES" : "NO");

📄 전체 소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class _32964 {

    private static int N;
    private static char[][] pipes;
    private static boolean canGoUp, canGoDown;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        pipes = new char[N][2];

        for (int r=0; r<2; r++) {
            String input = br.readLine();
            for (int c=0; c<N; c++) {
                pipes[c][r] = input.charAt(c);
            }
        }

        canGoUp = true;
        canGoDown = (pipes[0][1] == 'L');
        for (int i=1; i<N-1; i++) {
            boolean canGoUpNext = false;
            boolean canGoDownNext = false;
            if (canGoUp) {
                if (pipes[i][0] == 'I'){
                    canGoUpNext = true;
                }
                if (pipes[i][0] == 'L' && pipes[i][1] == 'L') {
                    canGoDownNext = true;
                }
            }
            if (canGoDown) {
                if (pipes[i][1] == 'I'){
                    canGoDownNext = true;
                }
                if (pipes[i][0] == 'L' && pipes[i][1] == 'L') {
                    canGoUpNext = true;
                }
            }
            canGoUp = canGoUpNext;
            canGoDown = canGoDownNext;
        }

        boolean result = (canGoUp && pipes[N-1][0] == 'L' || canGoDown);
        System.out.println(result ? "YES" : "NO");
    }

}

💡 최적화 솔루션

canGoUp 변수와 canGoDown 변수가 모두 false가 되는 순간이 오면 더 이상 탐색할 필요가 없다.

profile
입니다.

0개의 댓글