<2.10> 봉우리

mutexlocking·2022년 7월 20일
0

문제
: N by N의 격자판(2차원 배열) 이 주어진다. 이 격자판을 구성하는 각 element 값은 - 그 "지역"의 "높이" 로 간주한다. 그리고 이 격자판을 구성하는 N*N개의 지역 중, "각 지역을 기준으로 자신의 상-하-좌-우 보다 더 높이가 높은 지역"을 "봉우리"로 칭한다. (단 상-하-좌-우 지역의 높이를 비교할 때 , 가장자리를 벗어나면 높이를 0으로 간주한다.)
이때 N by N의 격자판이 입력으로 주어지면 , 이중 봉우리의 개수를 구하라.
(2<=N<=50 , 각 지역의 높이는 자연수 100을 넘지 않는다.)

이 문제의 요구사항은 주어진 대로 2차원 배열의 각 element 값을 비교하여 봉우리의 조건을 만족하는 element의 개수를 count 하는 것이다.

나는 이에 따른 해결로직으로 (row,col)의 값을 넘기면 , 그 위치의 element값을 (row,col-1) / (row, col+1) / (row-1, col) / (row+1, col)의 좌-우-상-하 값하고 비교하여 봉우리를 판단하는 방식을 생각했다.

그런데 이를 구현하는 방식에 었어 나와 선생님의 방식은 조금 차이가 있었다.

[구현 방식의 차이]
1. 나의 경우

  • 단순히 (row,col)의 값과 , (row,col-1) / (row, col+1) / (row-1, col) / (row+1, col)의 값을 4번 비교하여 , 그 결과를 && 연산자로 묶었다.
  • 이렇게 하면 요구하는 대로 각 지역 기준 , 좌-우-상-하 보다 모두 높이가 큰 지역을 찾을 수 있다.
  • 그러나 if문 안의 조건문이 or 중첩 if문을 사용한다면 if문의 크기가 커질 수 밖에 없고 -> 이는 가독성 저하로 나타난다.
  1. 선생님 방식
  • 반면 선생님 께서는 int[] row = {0 , 0, -1, 1} / int[] col = {-1, 1, 0, 0} 의 방향 배열을 사용하셨다.
  • 이 방향 배열을 for문과 함께 사용하면 , 4번의 비교를 같은 코드로 할 수 있고
    -> 이는 결과적으로 코드의 가독성을 높였다.
    (만약 비교해야할 횟수가 8개 12개라면 ? )
  • 따라서 이 방향 배열을 사용하는 방식으로 문제를 다시한번 풀어보았고 , 이 방식에 더 익숙해져야 겠다고 느꼈다.

[주목할 점]
: 사실 위의 차이보다 본질적으로 중요한 내용은, 가장자리를 벗어난 부분의 높이를 0으로 처리한다고 주어졌는데 -> 이를 코드로 어떻게 구현할 것인가 라고 생각한다.

  • 나의 경우는 문제의 예시 그림으로 가장자리가 모두 0으로 채워진 그림을 보고, 나 또한 입력받은 값을 기반으로 가장자리를 모두 0으로 채웠지만
  • 저 그림이 없없다면 가장자리를 0으로 채울 생각이 바로 들었을지 잘 모르겠다.
  • 이처럼 특정 문제의 조건이 주어졌을 때 -> 이를 어떤식으로 활용해야 할지를 떠올리는 능력을 키워야 겠다고 느꼈다.

아래는 내가 거대한 조건문을 쓴 if문으로 봉우리를 판단한 코드와,
선생님의 방식으로 방향 배열을 사용하여 봉우리를 판단한 코드를 첨부하겠다.

1) 나의 코드

import java.util.Scanner;

public class Main {

    public static int solution(int[][] arr, int N){
        int cntOfPeak = 0;

        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                if(isPeak(arr, i, j))
                    cntOfPeak++;
            }
        }

        return cntOfPeak;

    }

    public static boolean isPeak(int[][] arr, int centerRow, int centerCol){

        int centerValue = arr[centerRow][centerCol];

        if(centerValue > arr[centerRow-1][centerCol] && centerValue > arr[centerRow+1][centerCol]
                && centerValue > arr[centerRow][centerCol-1] && centerValue > arr[centerRow][centerCol+1])
            return true;
        else
            return false;
    }

    public static void main(String[] args) {

        //0.Scanner 준비
        Scanner sc = new Scanner(System.in);

        //1. 입력
        int N = sc.nextInt();

        //배열을 생성만 하고 초기화 하지 않으면 -> primitive 타입은 0으로 , 객체 타입은 null로 자동 초기화 됨 
        int[][] arr = new int[N+2][N+2];
        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                arr[i][j] = sc.nextInt();
            }
        }

        //2. solution() 호출하여 결과 반환
        int numOfPeaks = solution(arr, N);

        //3. 결과 출력
        System.out.println(numOfPeaks);
    }
}

2) 선생님 방식을 적용한 코드

import java.util.Scanner;

public class Main2 {

    static int[] row = {0, 0, -1, 1};
    static int[] col = {-1, 1, 0, 0};

    public static int solution(int[][] arr , int N){
        int numOfPeak = 0;

        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                if(isPeak(arr, i, j)) numOfPeak++;
            }
        }

        return numOfPeak;
    }

    public static boolean isPeak(int[][] arr, int centerRow, int centerCol){

        for(int i=0; i<4; i++){
            if(arr[centerRow][centerCol] <= arr[centerRow + row[i]][centerCol + col[i]])
                return false;
        }
        return true;
    }

    public static void main(String[] args) {
        //0.Scanner 준비
        Scanner sc = new Scanner(System.in);

        //1. 입력
        int N = sc.nextInt();

        //배열을 생성만 하고 초기화 하지 않으면 -> primitive 타입은 0으로 , 객체 타입은 null로 자동 초기화 됨
        int[][] arr = new int[N+2][N+2];
        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                arr[i][j] = sc.nextInt();
            }
        }

        //2. solution() 호출하여 결과 반환
        int numOfPeaks = solution(arr, N);

        //3. 결과 출력
        System.out.println(numOfPeaks);
    }
}
profile
개발자가 되고자 try 하는중

0개의 댓글