14890 - 경사로(java)

Byung Seon Kang·2022년 11월 23일
0

코드

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

/**
 * @Author: kbs
 */
public class Main {

    static int[][] arr;
    static int N, L, ans = 0;

    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());

        arr = new int[N][N];

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

        for (int i = 0; i < N; i++) {
            checkColumn(i);
            checkRow(i);
        }

        System.out.println(ans);
    }

    private static void checkRow(int row) {
        Queue<Integer> q = new ArrayDeque<>();
        for (int i = 0; i < N; i++) {
            q.add(arr[row][i]);
        }

        canGo(q);
    }

    private static void checkColumn(int column) {
        Queue<Integer> q = new ArrayDeque<>();
        for (int i = 0; i < N; i++) {
            q.add(arr[i][column]);
        }

        canGo(q);
    }

    private static void canGo(Queue<Integer> q) {
        boolean downSlope = false;
        int current;
        int count;

        while (!q.isEmpty()) {
            //1. 동일한 높이 계속 뽑는다.
            current = q.poll();
            count = pollEqualToCurrent(q, current);

            //이전에 아래로 경사가 있으면 설치 가능한지 체크한다.
            if (downSlope) {
                if (count < L) return;
                count -= L;
                downSlope = false;
            }

            //동일한거 뽑다가 끝까지 간 경우 리턴
            if (q.isEmpty()) {
                ans++;
                return;
            }

            //높이 2이상 차이나는 경우
            if (Math.abs(q.peek() - current) >= 2) return;

            //2. 높이가 달라졌을때.
            //우선 높이가 더 낮아진 경우엔 다음걸로 체크해야된다.
            if (current > q.peek()) {
                downSlope = true;
                continue;
            }

            //높이가 높아졌을 땐 현재 count 체크
            if (current < q.peek()) {
                if (count < L) return;
            }
        }

        ans++;
    }

    private static int pollEqualToCurrent(Queue<Integer> q, int current) {
        int count = 1;
        while (!q.isEmpty() && current == q.peek()) {
            q.poll();
            count++;
        }
        return count;
    }
}
  • 높이가 낮아진 경우에 대해 엣지케이스를 처리하느라 시간이 엄청 들었다.
  • 높이가 낮아졌을 때 downSlope boolean값을 true로 만들고, 다시 동일한 높이의 바닥 길이를 재서 L보다 작으면 불가
    • L보다 크면 가능한데 여기서 문제가 생겼다.
    • 다시 이후에 높이가 높아진 경우를 어떻게 생각해야되지?
      • 그냥 이전에 계산했던 count-L을 그대로 활용했다.
      • 인덱스 포지션 잡는 시간이 너무 오래걸림.
profile
왜 필요한지 질문하기

0개의 댓글