[백준][1041] 주사위

suhan0304·2023년 11월 13일
0

백준

목록 보기
34/53
post-thumbnail


문제

주사위의 각 면에는 수가 주어지고 해당 주사위를 쌓아서 NxNxN 크기의 정육면체를 만들 때 보이는 5개의 면에 쓰여 있는 수의 합의 최솟값을 출력하는 프로그램을 작성하시오.

입력

  • 첫째 줄, N이 주어진다.
  • 둘째 줄, A, B, C, D, E, F가 주어진다.

출력

  • 합의 최솟값을 출력한다.

풀이

주사위를 쌓아서 NxNxN 크기의 정육면체를 만들면 다음과 같은 세 가지 케이스가 있다.

  • 주사위의 한 면만 보이는 경우
  • 주사위의 연속된 두 면만 보이는 경우
  • 주사위의 한 모시를 중심으로 하는 세 면만 보이는 경우

이 때 한 변의 길이를 n이라고 하면 공식을 세울 수 있다. 아래 그림을 참고하면 이해하기 쉽다.

따라서 1면의 합의 최소, 2면의 합의 최소, 3면의 합을 구해 위 공식에 각각 곱해줘서 다 더해주면 결과를 구할 수 있다. 이 때 중요한 점은 2면의 경우에는 연속된 두 면으로 마주보고 있는 면을 제외처리 해주어야하고 3면의 경우 한 꼭짓점을 기준으로 3면이 모여있어야해서 3면 중 어떤 면도 마주보고 있는 경우를 제외해야한다.

이 문제의 입력으로 주는 A, B, C, D, E, F를 인덱스로 치환하면 0, 1, 2, 3, 4, 5인데 이를 위 문제의 그림에 넣어보면 마주보는 면의 인덱스 합이 5가 되도록 그림을 맞춰주었다.
아무래도 인덱스를 이용해서 마주보는 면을 확인하라고 이렇게 친절하게 준 것 같다.

따라서 이중, 삼중 반목문으로 2면 합의 최소, 3면 합의 최소를 구하면서 마주보는 면이 있을때만 제외처리를 하도록 코딩을 할 수 있다.

이 때 특이한 경우가 딱 하나 n = 1일때 특이한 케이스가 주어지는데 이 때는 가장 큰 면을 바닥으로 하고 주사위를 하나 놓기 때문에 정렬한 후에 가장 큰수를 빼고 더해주어 결과를 출력하도록 예외처리를 진행했다.


코드

import sys

input = sys.stdin.readline

n = int(input())
dice = list(map(int, input().split()))

min_1 = min(dice)
min_2 = 2 * (10**6)
min_3 = 3 * (10**6)
for i in range(6):
    for j in range(i + 1, 6):
        if dice[i] + dice[j] < min_2:
            if i + j != 5:
                min_2 = dice[i] + dice[j]
        for k in range(j + 1, 6):
            if dice[i] + dice[j] + dice[k] < min_3:
                if i + j != 5 and j + k != 5 and k + i != 5:
                    min_3 = dice[i] + dice[j] + dice[k]

ans = 0
if n == 1:
    ans = sum(sorted(dice)[:5])
else:
    ans += min_1 * ((n - 1) * (n - 2) * 4 + (n - 2) * (n - 2))
    ans += min_2 * ((n - 1) * 4 + (n - 2) * 4)
    ans += min_3 * 4
print(ans)
profile
Be Honest, Be Harder, Be Stronger

0개의 댓글