해커랭크(Problem Solving)
3D Surface Area
감전우
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일 경우 이 방식이 먹히지 않으므로 따로 처리해줘야 한다.
지금까지 구한 값들의 총 합이 전체 겉넓이다.