본문 바로가기
알고리즘 풀이/백준

[백준 16931] 겉넓이 구하기(python)

by char_lie 2023. 3. 17.
반응형

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

 

16931번: 겉넓이 구하기

크기가 N×M인 종이가 있고, 종이는 1×1크기의 칸으로 나누어져 있다. 이 종이의 각 칸 위에 1×1×1 크기의 정육면체를 놓아 3차원 도형을 만들었다. 종이의 각 칸에 놓인 정육면체의 개수가 주어

www.acmicpc.net

겉넓이 구하기 문제

정육면체 여러 개로 이루어진 도형의 겉넓이를 구해보는 문제

겉넓이의 성질을 이해하면 풀 수 있는 문제

내가 푼 정답코드

import sys
N, M = map(int, sys.stdin.readline().split())
square = [list(map(int, sys.stdin.readline().split())) for _ in range(N)] 
side1 = 0 # 왼쪽에서 볼때
side2 = 0 # 오른쪽에서 볼때
side3 = N*M #위나 아래에서 볼때

for i in range(N):
    for j in range(M):
        if j == 0: # 맨 앞면
            side1 += square[i][j] 
        else : #앞면 아니면
            if square[i][j] > square[i][j-1]: #다음 블록이 이전꺼보다 커!
                side1 += square[i][j] - square[i][j-1] # 그럼 차이만큼 더하자

for j in range(M):
    for i in range(N):
        if i == 0: # 맨 앞면
            side2 += square[i][j] 
        else : #앞면 아니면
            if square[i][j] > square[i-1][j]: #다음 블록이 이전꺼보다 커!
                side2 += square[i][j] - square[i-1][j] # 그럼 차이만큼 더하자
print((side1+side2+side3)*2)

📌 문제 접근 포인트

1. 정육면체로 이루어진 도형의 겉넓이는 6면을 모두 구할 필요 없이, 3면만 구하면 된다. (대칭을 이루기 때문)
2. 바닥면은 갯수가 고정이므로 N*M으로 바로 알 수 있다. 그래서 2면만 구해주면 된다.
3. 단순하게 봤을때 (예시기준) 한쪽 면에서 봤을 때 갯수를 다 더하면 된다고 생각하기 쉽지만, 실제 답인 60과 다르게 58로 나온다. 이는 블록이 4개, 3개, 4개로 쌓인 구간 사이의 부분을(아래 V표시된 블럭 및 마주보는 블럭) 고려하지 않게 되기 때문에 2개 많큼 비어버린다.
4. 그렇기에 앞에서부터 정직하게 겉넓이를 세어나가면 쉽게 구할 수 있다.
5. 맨 처음 앞면의 높이를 더해주고, 그 뒤부터는 앞에꺼보다 뒤에꺼가 더 클때 차이만큼씩 더해주면 쉽게 구할 수 있다.


느낀 점

은근히 낚시를 섞은 문제이다. (3번 포인트) 처음에 아무리 봐도 58인데 왜 60이지? 하면서 한참을 고민했다가, 가운데 부분을 발견했고, 그냥 보이는 그대로 구현하면 되겠다는 생각에 구현을하면 어렵지 않게 풀 수 있던 문제였다.

반응형

댓글