개킹받는 문제
발상의 전환에 실패해서 골드2 문제보다 힘들게 풀었다
2^i 길이를 한 변으로 갖는 여러 가지 정육면체로
length X width X height의 부피를 갖는 박스를 채울 정육면체의 최소 개수를 구하기
설명이 개발새발인데 아래 코드를 보면서 다시 이해해보자.
import sys
input = sys.stdin.readline
length, width, height = map(int, input().split())
total = length * width * height
N = int(input())
cube = [tuple(map(int, input().split())) for _ in range(N)]
cube.sort(reverse=True)
answer, total_now = 0, 0
for c_idx, c_cnt in cube:
total_now *= 8 # 다음 순서 = 이전 정육면체 부피의 1/8이므로 이전까지의 개수에 8을 곱해줌 (예 : 4*4*4 1개 = 2*2*2 8개)
c_len = 2**c_idx
cnt_limit = (length // c_len) * (width // c_len) * (height // c_len) - total_now # 현재 공간에 채울 수 있는 개수 - 지금까지 채운 개수
cnt_limit = min(c_cnt, cnt_limit) # 실제로 채우기 가능한 개수
answer += cnt_limit
total_now += cnt_limit
if total_now == total:
print(answer)
else:
print(-1)
우선 정육면체의 정보를 cube
라는 리스트 변수에 저장하였다.
그리고 큰 정육면체부터 공간에 채워넣어야 그리디한 결과를 낼 수 있기에 sort()
함수로 리스트를 내림차순으로 정렬하였다.
그 아래의 for
문은 백준에서 주어준 예시가 처리되는 과정으로 이해해보도록 하겠다.
4 4 8
3
0 10
1 10
2 1
가 입력된 예시이다.
2-1. 우선 첫 iteration에서 total_now
에 8을 곱해주는 과정은 total_now
가 0이므로 의미가 없다.
2-2. 가로, 세로, 높이를 현재 iteration의 정육면체 한 변의 길이로 각각 나누어 곱한다. 그러면 현재 정육면체로 채울 수 있는 최대한의 개수를 얻을 수 있다. 예시를 기준으로 말하면
(4 / 4) X (4 / 4) X (8 / 4) = 2
2개를 채울 수 있게 된다. 하지만 예시에서 주어진 4X4X4 정육면체는 1개 이므로 1개만 채운다고 기록해둔다.
2-3. 이제 다음 iteration으로 넘어가면 이번에는 2X2X2의 정육면체이다. 이전 iteration에서 4X4X4 정육면체 1개를 채웠다고 기록해두었는데, 4X4X4 1개는 2X2X2 8개와 부피가 같기 때문에 2X2X2 정육면체와 비교하려면 이것에 8을 곱해주어야 한다.
2-4. 그래서 total_now
가 1에서 8이 되고, 이전 iteration과 똑같이 전체 부피에 2X2X2로 채울 수 있는 최대한의 개수를 계산한다. 예제에 따르면 (4 / 2) X (4 / 2) X (8 / 2) = 16개이다. 그런데 이전 iteration에서 4X4X4 정육면체 1개, 즉 2X2X2 정육면체 8개를 이미 채워뒀다고 기록해둔 상태이므로, 추가로 채울 수 있는 2X2X2 정육면체의 개수는 16 - 8 = 8개가 최대이다.
2-5. 그리고 현재 가지고 있는 2X2X2 정육면체의 개수는 10개이므로 당연히 8개를 채울 수 있다. 그래서 8개를 더 채웠다는 의미로 total_now
에 8을 더해준다. 그래서 total_now
= 16이 된다.
2-6. 이제 마지막으로 1X1X1 정육면체로 채울 수 있는 개수를 세야한다. (사실 이미 공간이 다 찬 상태지만 일단은 진행한다) 이전까지 2X2X2 정육면체 16개를 채웠으므로 이것에 8을 곱하여 1X1X1 정육면체로 변환한다. 즉 16 X 8 = 128개, 그리고 박스의 전체 부피는 4 X 4 X 8 = 128이다. 1X1X1 정육면체로 채우면 당연히 부피값만큼 들어가지는데 이미 128개를 채웠다. 즉 128 - 128 = 0이기 때문에 더이상 채울 수 있는 자리가 없다.
2-7. iteration이 종료되고 total
변수와 total_now
변수가 같은지 확인한다. 같으면 answer
변수에 기록해두었던 정육면체 개수를 print
하여 정답처리.
이해가 안갔었는데 상세하게 풀이해주셔서 감사합니다 !!