감전우 2019. 11. 3. 11:30

문제: 3D Surface Area

난이도: Medium

 

문제 설명

 모서리의 길이가 1인 정육면체가 n x m의 영역 안에 각각 임의의 높이로 쌓여있을 때 겉넓이를 구하여라.

 예를 들어, 위의 경우에는 겉넓이가 60이다.

 

문제 해결

소스 코드

    static int surfaceArea(int[][] A) {
        int y = A.length;
        int x = A[0].length;
        int up = 0;
        int front = 0;
        int side = 0;
        int frontTemp = 0;
        int sideTemp = 0;
        int result = 0;

        for(int i = 0; i < y; i++) { // 위, 아래
            for(int j = 0; j < x; j++) {
                if(A[i][j] > 0) {
                    up += 2;
                }
            }
        }

        for(int i = 0; i < y; i++) { // 왼쪽, 오른쪽
            if(x == 1) {
                side += (A[i][0] * 2);
            } else {
                sideTemp = A[i][0] + A[i][x-1];
                for(int j = 0; j < (x-1); j++) {
                    sideTemp += Math.abs(A[i][j] - A[i][j+1]);
                }
                side += sideTemp;
            }
        }

        for(int i = 0; i < x; i++) { // 앞, 뒤
            if(y == 1) {
                front += (A[0][i] * 2);
            } else {
                frontTemp = A[0][i] + A[y-1][i];
                for(int j = 0; j < (y-1); j++) {
                    frontTemp += Math.abs(A[j][i] - A[j+1][i]);
                }
                front += frontTemp;
            }
        }

        result = up + front + side;
        return result;
    }

 

해설

 , 아래의 경우에는 각각의 좌표를 탐색하여 블록이 하나라도 있으면 1, 없으면 0의 값을 모두 더한 값의 2배로 쉽게 구할 수 있다.

 왼쪽, 오른쪽의 경우는 먼저 왼쪽 끝과 오른쪽 끝의 넓이를 얻고, 각각의 행을 왼쪽부터 오른쪽으로 탐색해 서로의 차이를 모두 더한 값을 구하여 합치면 된다. 예시의 그림에서는 다음과 같이 구해진다.

 

1  3  4

2  2  3

1  2  4

1: 1(왼쪽 끝) + 4(오른쪽 끝) + 2 + 1 = 8

2: 2 + 3 + 0 + 1 = 6

3: 1 + 4 + 1 + 2 = 8

 

, 뒤의 경우는 왼쪽, 오른쪽의 경우에서 탐색 방향만 바꾸면 된다.

 주의할 점이 있는데, 행 또는 열의 길이가 1일 경우 이 방식이 먹히지 않으므로 따로 처리해줘야 한다.

 지금까지 구한 값들의 총 합이 전체 겉넓이다.