1️⃣ 문제 설명

16931번: 겉넓이 구하기

스크린샷 2022-10-10 오전 1.42.27.png


2️⃣ 풀이

한 정육면체의 겉넓이는 6이고, 겹쳐서 가려지는 부분을 빼서 전체 겉넓이를 구한다

1. 정육면체 한 개당 넓이 6을 계산하여 한 칸의 전체 겉넓이를 가지고 있는 배열 area 생성
2. 상하좌우 가려지는 칸을 검사해야하기 때문에 d로 방향을 처리
3. 옆(혹은 위아래) 칸이 자신보다 높거나 같을 경우, 자신의 높이만큼 빼준다(다 가려지기 떄문)
   옆(혹은 위아래) 칸이 자신보다 낮을 경우, 낮은 칸 만큼 빼준다(해당 칸 까지는 가려지기 때문)
4. 층이 올라가는 경우 처리 >> 결국 맨 밑과 맨 윗면만 노출
		1이나 2면 2칸만, 3부터는 2가 되도록 처리
5. area 배열의 요소들을 다 더하여 정답 산출

3️⃣ 나의 코드

const [[N, M], ...arr] = require("fs")
	.readFileSync("./dev/stdin")
	.toString()
	.trim()
	.split("\\n")
	.map((v) => v.split(" ").map(Number));

//1.
const area = arr.map((v) => v.map((v2) => 6 * v2));

//2.
const d = [
	[0, -1],
	[0, 1],
	[-1, 0],
	[1, 0],
];

for (let i = 0; i < N; i++) {
	for (let j = 0; j < M; j++) {
		const arrV = arr[i][j];

		for (const [di, dj] of d) {
			const [ni, nj] = [i + di, j + dj];
			if (ni < 0 || nj < 0 || ni >= N || nj >= M) continue;
			//3.
			const nearV = arr[ni][nj];
			if (arrV <= nearV) {
				area[i][j] -= arrV;
			} else {
				area[i][j] -= nearV;
			}
		}

		//4.
		if (arrV === 2) {
			area[i][j] -= 2;
		}
		if (arrV > 2) {
			area[i][j] -= 2 * arrV - 2;
		}
	}
}

const answer = area.map((v) => v.reduce((a, b) => a + b)).reduce((a, b) => a + b);

console.log(answer);

4️⃣ 마무리

개인적으로 조금 뿌듯했던 문제이다

시간은 좀 걸렸지만 처음 생각했던대로 구현을 하여 정답이 됐다

검색해서 나오는 풀이들과 다르게 풀기도 했고 node.js로는 나 포함 6명 밖에 맞춘 사람이 없어서 뭔가 기분이 더 좋았다