티스토리 뷰

알고리즘/백준

백준 14890 (경사로) - java

김다미김태리신시아 2023. 8. 14. 14:18

https://www.acmicpc.net/problem/14890

 

14890번: 경사로

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

www.acmicpc.net

유형 : 구현

접근 

  • 열과 행은 각각 다르게 적용된다 ! (일괄적용이 아님을 주의)
  • 열과 행에 대한 메소드 구현 후 모든 행 , 열에 적용

전체 코드

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

public class Main {
    static int n = 0;
    static int m = 0;

    static int[][] board;

    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());
        m = Integer.parseInt(st.nextToken());
        board = new int[n+1][n+1];
        boolean[][] visit = new boolean[n+1][n+1];

        for(int i=1;i<=n;i++){
            st = new StringTokenizer(br.readLine(), " ");
            for(int j=1;j<=n;j++){
                board[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int count = 0;
        for(int i=1;i<=n;i++){
            if(sero(i,visit)){
                count = count + 1; // 모든 열에 대해 수행
            }
        }

        visit = new boolean[n+1][n+1];
        for(int i=1;i<=n;i++){
            if(garo(i,visit)){
                count = count + 1; // 모든 행에 대해 수행
            }
        }

        System.out.println(count);
        br.close();
    }
    /*(세로)*/
    static boolean sero(int col,boolean[][] visit)
    {
        int idx = 1;
        boolean result = false; // 끝까지 완주 가능한지 여부 -> true , count = count + 1
        while(idx <= n){

            if(idx == n) {
                result = true; // n에 도달한 경우 메소드 종료
                break;
            }
            // 다음 행의 값과의 차이
            int minus = Math.abs(board[idx][col] - board[idx+1][col]);

            if(minus == 0) {
                idx = idx + 1; // 동일할 경우 이동
            }

            else if(minus == 1){
                // 1인 경우 -1 : 작아지는 경우 -> 내리막길
                if(board[idx][col] > board[idx+1][col]){
                    int des = idx + m;
                    int num = board[idx+1][col]; // 기준 값

                    if(des > n)
                        break; // 경사로 설치 불가

                    boolean keep = true;
                    // 경사로 설치
                    for(int i = idx+1;i<=des;i++){

                        if(visit[i][col]) {
                            keep = false;
                            break; // 이미 다른 경사로가 놓여진 경우
                        }

                        if(board[i][col] == num) {
                            visit[i][col] = true; // 설치
                        }

                        else{
                            keep = false;
                            break; // 기준 값과 다르다면
                        }
                    }

                    if(!keep) {
                        break; // 아예 종료
                    }
                }
                // 값이 1 -2 : 오르막길
                else{
                    int des = idx + 1 - m;
                    int num = board[idx][col];

                    if(des < 1)
                        break;

                    boolean keep = true;

                    for(int i = idx;i>= des;i--){

                        if(visit[i][col]) {
                            keep = false;
                            break;
                        }

                        if(board[i][col] == num) {
                            visit[i][col] = true;
                        }

                        else{
                            keep = false;
                            break;
                        }
                    }

                    if(!keep) {
                        break;
                    }
                }

                idx = idx + 1; // 경사로 설치 후 이동
            }

            else{
                result = false; // 값이 2이상인 경우 경사로 설치 불가
                break;
            }
        }
        return result;
    }

    static boolean garo(int row,boolean[][] visit){
        int idx = 1;
        boolean result = false;
        while(idx <= n){

            if(idx == n) {
                result = true;
                break;
            }

            int minus= Math.abs(board[row][idx] - board[row][idx+1]);

            if(minus == 0){
                idx = idx + 1;
            }

            else if(minus == 1){

                if(board[row][idx] > board[row][idx+1]){
                    int des = idx + m;
                    int num = board[row][idx+1];

                    if(des > n)
                        break;

                    boolean keep = true;

                    for(int i = idx+1;i<=des;i++){

                        if(visit[row][i]) {
                            keep = false;
                            break;
                        }

                        if(board[row][i] == num) {
                            visit[row][i] = true;
                        }

                        else{
                            keep = false;
                            break;
                        }
                    }

                    if(!keep) {
                        break;
                    }
                }

                else{
                    int des = idx + 1 - m;
                    int num = board[row][idx];

                    if(des < 1)
                        break;

                    boolean keep = true;

                    for(int i = idx;i>= des;i--){

                        if(visit[row][i]) {
                            keep = false;
                            break;
                        }

                        if(board[row][i] == num) {
                            visit[row][i] = true;
                        }

                        else{
                            keep = false;
                            break;
                        }
                    }

                    if(!keep) {
                        break;
                    }
                }

                idx = idx + 1;
            }

            else{
                result = false;
                break;
            }

        }
        return result;
    }
}