백준 경사로

KIMYEONGJUN·2026년 3월 20일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다.
둘째 줄부터 N개의 줄에 지도가 주어진다.
각 칸의 높이는 10보다 작거나 같은 자연수이다.

첫째 줄에 지나갈 수 있는 길의 개수를 출력한다.

내가 이 문제를 보고 생각해본 부분

main에서는 입력을 받아 2차원 배열에 지도를 저장한다.
각 행과 각 열을 따로 떼어내어 canPass() 함수에 넘겨 길을 판단한다.
canPass 함수는 다음을 수행한다:
경사로가 놓인 칸을 체크하기 위해 used 배열을 만든다.
한 칸씩 현재 칸과 다음 칸의 높이 차를 계산한다.
높이 차가 0이면 그냥 넘어간다.
1보다 크면 바로 지나갈 수 없다.
다음 칸이 더 높은 경우, 현재 칸을 기준으로 뒤로 L칸 연속 같은 높이와 경사로 미설치인지 확인 후 설치한다.
다음 칸이 더 낮은 경우, 다음 칸부터 L칸 연속 같은 높이와 경사로 미설치인지 확인 후 설치한다.
위 과정 중 조건을 만족하지 않으면 false를 반환해 해당 길이 통과 불가임을 표시한다.
모든 행과 열을 검사해서 통과 가능한 길의 총 개수를 출력한다.

코드로 구현

package baekjoon.baekjoon_33;

import java.io.*;
import java.util.*;

// 백준 14890번 문제
public class Main1332 {
    static int N, L;
    static int[][] map;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        L = Integer.parseInt(st.nextToken());

        map = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int result = 0;

        // 모든 행 검사
        for (int i = 0; i < N; i++) {
            if (canPass(map[i])) result++;
        }

        // 모든 열 검사
        for (int j = 0; j < N; j++) {
            int[] col = new int[N];
            for (int i = 0; i < N; i++) {
                col[i] = map[i][j];
            }
            if (canPass(col)) result++;
        }

        System.out.println(result);
        br.close();
    }

    // 길이 지나갈 수 있는지 판단하는 함수
    private static boolean canPass(int[] line) {
        boolean[] used = new boolean[N]; // 경사로 설치 여부
        for (int i = 0; i < N - 1; i++) {
            int diff = line[i + 1] - line[i];

            if (diff == 0)
                continue; // 높이 같으면 통과

            if (Math.abs(diff) > 1)
                return false; // 높이 차이가 1 초과

            if (diff == 1) {
                // 다음 칸이 높음 -> 현재 칸 기준으로 L칸 연속 같은 높이 있는지 확인
                for (int j = i; j > i - L; j--) {
                    if (j < 0 || line[j] != line[i] || used[j]) {
                        return false; // 조건 만족하지 않으면 통과 불가
                    }
                    used[j] = true; // 경사로 설치 표시
                }
            } else if (diff == -1) {
                // 다음 칸이 낮음 -> 다음 칸부터 L칸 연속 같은 낮은 높이인지 확인
                for (int j = i + 1; j <= i + L; j++) {
                    if (j >= N || line[j] != line[i + 1] || used[j]) {
                        return false; // 조건 만족하지 않으면 통과 불가
                    }
                    used[j] = true; // 경사로 설치 표시
                }
            }
        }
        return true;
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글