Algorithm/BOJ

14890. 경사로

 

 

경사로를 놓는 조건

 

- 경사로는 낮은 칸에 놓으며, L개의 연속된 칸에 경사로의 바닥이 모두 접해야 한다.

- 낮은 칸과 높은 칸의 높이 차이는 1이어야 한다.

- 경사로를 놓을 낮은 칸의 높이는 모두 같아야 하고, L개의 칸이 연속되어 있어야 한다.

 

경사로를 놓을 수 없는 조건

 

- 경사로를 놓은 곳에 또 경사로를 놓는 경우

- 낮은 칸과 높은 칸의 높이 차이가 1이 아닌 경우

- 낮은 지점의 칸의 높이가 모두 같지 않거나, L개가 연속되지 않은 경우

- 경사로를 놓다가 범위를 벗어나는 경우



주의사항

 

1. 내려갈 때는 이전에 경사로를 설치하든 말든 상관없다.

2. 올라가야하는 상황에서 그동안 온 인덱스가 L보다 작으면 설치할 수 없다.

3. 내려가는 상황에서 (N - 현재인덱스) < L 이면 설치할 수 없다.

4. 올라가는 상황이면 이전의 L만큼의 블럭을 확인하여 평지가 맞는지, 경사로가 설치되었는지 체크해야한다.

 

 

 

 

 

 

 

 

더보기
더보기
import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static int N, L, ans;
    public static int[][] MAP;

    public static void InputData() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
        N = Integer.parseInt(stk.nextToken());
        L = Integer.parseInt(stk.nextToken());

        MAP = new int[N][N];

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

        br.close();
    }
    //데이터 입력

    public static void Print_result() throws IOException {
        BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write(String.valueOf(ans));
        bw.flush(); bw.close();
    }
    // 결과 출력

    public static void Check(boolean row){
        for(int i = 0; i < N; i++){
            int prev_Height = row ? MAP[i][0] : MAP[0][i]; //이전 칸의 높이
            int dist = 0; //경사로 길이 체크
            boolean[] drop = new boolean[N];

            for(int j = 1; j < N; j++){
                int now_Height = row ? MAP[i][j] : MAP[j][i];
                int dist_diff = Math.abs(now_Height - prev_Height);
                boolean escape = false;

                switch(dist_diff){
                    case 0:
                        if(dist > 0) {
                            drop[j - 1] = true;
                            dist--;
                        }
                        break;
                    case 1:
                        if(now_Height > prev_Height){
                            if(j < L || dist > 0 || drop[j - L]){
                                escape = true;
                                break;
                            }

                            for(int k = 1; k <= L; k++){
                                drop[j - k] = true;
                            }
                        }else{
                            if(dist > 1){
                                escape = true;
                                break;
                            }
                            dist = L;
                        }
                        break;
                    default:
                        escape = true;
                        break;
                }


                if(escape || (j == N - 1 && dist > 1)){
                    ans--;
                    break;
                }

                prev_Height = now_Height;
            }
            ans++;
        }
    }
    // 행열 체크


    public static void main(String[] args) throws IOException{
        InputData();

        Check(true);
        Check(false);

        Print_result();
    }
}