백준 14890 경사로 (Java,자바)

jonghyukLee·2021년 10월 1일
0

이번에 풀어본 문제는
백준 14890번 경사로 입니다.

📕 문제 링크

❗️코드

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

public class Main {
    static int N,L,answer;
    static int [][] map;
    static boolean [][] isVis;
    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());
            }
        }

        isVis = new boolean[N][N];
        for(int i = 0; i < N; ++i)
        {
            horizon(i,map[i][0]);
        }
        isVis = new boolean[N][N];
        for(int i = 0; i < N; ++i)
        {
            vertical(i,map[0][i]);
        }
        System.out.print(answer);
    }
    static void horizon(int n, int h)
    {
        int j = 0;
        int cur = h;
        while(true)
        {
            if(j == N-1)
            {
                answer++;
                break;
            }
            if(map[n][j+1] == cur) j++; // 다음칸과 동일
            else if(Math.abs(map[n][j+1] - cur) >= 2) break; // 높이 2이상 차이
            else // 높이 1차이
            {
                int next_h = map[n][j+1];
                if(cur > next_h) // down
                {
                    if(j+L >= N) break;
                    int startPoint = j+1;

                    for(int idx = startPoint; idx < startPoint+L; ++idx)
                    {
                        if(map[n][idx] != next_h || isVis[n][idx]) return;
                        isVis[n][idx] = true;
                    }
                    j += L;
                    cur--;
                }
                else // up
                {
                    if(j-L+1 < 0) break;
                    for(int idx = j; idx > j-L; --idx)
                    {
                        if(map[n][idx] != cur || isVis[n][idx]) return;
                        isVis[n][idx] = true;
                    }
                    j++;
                    cur++;
                }
            }
        }
    }
    static void vertical(int n, int h)
    {
        int i = 0;
        int cur = h;
        while(true)
        {
            if(i == N-1)
            {
                answer++;
                break;
            }
            if(map[i+1][n] == cur) i++; // 다음칸과 동일
            else if(Math.abs(map[i+1][n] - cur) >= 2) break; // 높이 2이상 차이
            else // 높이 1차이
            {
                int next_h = map[i+1][n];
                if(cur > next_h) // down
                {
                    if(i+L >= N) break;
                    int startPoint = i+1;

                    for(int idx = startPoint; idx < startPoint+L; ++idx)
                    {
                        if(map[idx][n] != next_h || isVis[idx][n]) return;
                        isVis[idx][n] = true;
                    }
                    i += L;
                    cur--;
                }
                else // up
                {
                    if(i-L+1 < 0) break;
                    for(int idx = i; idx > i-L; --idx)
                    {
                        if(map[idx][n] != cur || isVis[idx][n]) return;
                        isVis[idx][n] = true;
                    }
                    i++;
                    cur++;
                }
            }
        }
    }
}

📝 풀이

구현 문제입니다.
각 끝점을 시작으로 가로, 세로 한번씩 탐색하도록 구성해 보았습니다.
현재 위치의 높이값을 계속 갱신하여 높이가 같을경우 다음인덱스로, 높이가 서로 다를경우 내리막인지, 오르막인지를 확인하여 경사로를 세우게 됩니다. 범위를 벗어났을 시 즉시 반복문을 벗어나고, 경사로를 세울 조건에 맞는다면 경사로를 세운 뒤 방문배열에 표시해줍니다. 겹치는 경사로가 없어야 하기 때문입니다. 앞선 방식으로 모든 경우의 수를 탐색해주면 결과의 갯수를 구할 수 있습니다.

📜 후기

오르막과 내리막을 구분하는 것 이외에는 딱히 복잡하지 않았던 것 같습니다.
개인적으로 구현문제를 좋아해서 아주 재밌게 풀었습니다 ㅎㅎ
제출해서 한방에 해결하면 기분이 참 좋은 것 같아요!

profile
머무르지 않기!

0개의 댓글