공부 기록장

백준 1041. 주사위 본문

코딩 테스트/백준 문제 풀이

백준 1041. 주사위

빛나무 2024. 1. 8. 14:55

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

 

1041번: 주사위

첫째 줄에 N이 주어진다. 둘째 줄에 주사위에 쓰여 있는 수가 주어진다. 위의 그림에서 A, B, C, D, E, F에 쓰여 있는 수가 차례대로 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, 쓰여 있는 수

www.acmicpc.net

코드

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

if n == 1:
    num.sort()
    num.pop()
    print(sum(num))
    exit(0)

case = []
case.append((num[0], num[1], num[2]))
case.append((num[0], num[2], num[4]))
case.append((num[0], num[3], num[4]))
case.append((num[0], num[1], num[3]))
case.append((num[1], num[2], num[5]))
case.append((num[2], num[4], num[5]))
case.append((num[3], num[4], num[5]))
case.append((num[1], num[3], num[5]))

minSum = sum(case[0])
idx = 0
for i in range(1, len(case)):
    if sum(case[i]) < minSum:
        minSum = sum(case[i])
        idx = i

tmp = []
for c in case[idx]:
    tmp.append(c)

tmp.sort()
one = tmp[0]
two = one + tmp[1]
three = two + tmp[2]

top = three * 4 + two * 8 * (n-2) + one * 5 * (n-2) ** 2
bottom = two * 4 + one * 4 * (n-2)
print(top + bottom)

 

정답 비율과 문제를 읽으면서 쫄았지만!

정육면체를 직접 그려보고 최소가 되려면 어떻게 해야 할 지

고민을 좀만 하니 수월하게 풀린 문제였다.

 

일단 처음 생각은 NxNxN 형태의 정육면체로 쌓아 올렸을 때,

겉으로 드러나는 주사위 면이 최소가 되어야겠구나 하는 생각이 들었고,

정육면체의 부위 별로 드러나는 주사위의 면의 개수가 다르기 때문에

부위 별로 나누어서 보여지는 면의 개수를 세어 보았다.

 

n이 2 이상인 경우에 대해서,

크게 맨 밑 층 이외의 층맨 밑 층으로 나누었다.

 

1. 맨 밑 층 이외의 층

1) 코너는 3면 보임 → 4개

2) 모서리는 2면 보임 → 8 * (N-2) 개

3) 면은 1면 보임 → 5 * (N-2)^2 개

 

2. 맨 밑 층

1) 코너는 2면이 보임 → 4개

2) 모서리는 1면이 보임 → 4 * (N-2) 개

 

이렇게 나누고 코드를 구현했는데 통과가 안됐다.

 

내가 간과한 점은 2면 혹은 3면이 보여질 때,

주사위의 숫자 구성이 어떻게 되어 있느냐에 따라 꼭 최소값으로 보여지지 않을 수 있다는 점이었다.

 

주사위의 3면이 최솟값으로 보이면 2면과 1면도 최솟값으로 보일 수 있기 때문에,

주어진 주사위 1개에 대해서,

주사위의 3면이 보일 수 있는 8가지 경우의 수를 전부 고려해보고 최솟값을 구하는 과정을 거쳤다.

 

N이 1인 경우는 따로 처리해주었다.