코딩테스트/python
[programmers/python] 최소직사각형 - 완전탐색
zyin
2025. 5. 21. 05:48
문제 설명
회사는 명함을 수납할 수 있는 지갑을 만들려고 한다. 모든 명함을 돌리거나 눕힐 수 있다는 전제하에, 모든 명함을 한 지갑 안에 넣을 수 있도록 가장 작은 지갑의 크기를 구해야 한다.
예를 들어 다음과 같은 명함 정보가 있다고 하자:
명함 번호 | 가로 | 세로 |
1 | 60 | 50 |
2 | 30 | 70 |
3 | 60 | 30 |
4 | 80 | 40 |
이 명함들을 적절히 눕혀 넣으면, 80(가로) x 50(세로)의 지갑으로 모두 수납할 수 있고, 이는 최소 크기인 4000이 된다.
핵심 아이디어
모든 명함은 회전이 가능하므로, 각 명함의 긴 변을 가로로, 짧은 변을 세로로 본다고 해도 무방하다. 즉, 모든 명함의 [가로, 세로]를 sorted()를 통해 [작은 쪽, 큰 쪽]으로 정리한 후:
- 가로 길이의 최댓값 (긴 쪽)
- 세로 길이의 최댓값 (짧은 쪽)
을 곱하면, 모든 명함을 수납할 수 있는 지갑의 최소 크기를 얻을 수 있다.
이처럼 각 명함을 두 가지 방향으로 전환해보는 모든 경우의 수를 탐색하는 방식은 완전탐색(Brute-force)에 해당한다.
구현 코드
def solution(sizes):
# 각 명함을 짧은 쪽, 긴 쪽 순으로 정렬
sizes_sorted = [sorted(size) for size in sizes]
# 각 방향에서 최대값 찾기
max_w = max(s[0] for s in sizes_sorted) # 가로 최댓값 (짧은 쪽)
max_h = max(s[1] for s in sizes_sorted) # 세로 최댓값 (긴 쪽)
return max_w * max_h
코드 설명
- sorted(size)로 각 명함을 [작은 쪽, 큰 쪽] 순서로 정리한다.
- 모든 명함 중 가장 큰 **짧은 변(max_w)**과 가장 큰 **긴 변(max_h)**을 구한다.
- 그 둘을 곱한 값이 지갑의 최소 크기이다.
이 방식은 완전탐색이라고 볼 수 있는데, 이유는 다음과 같다:
- 각 명함마다 회전 여부를 고려한다 → 경우의 수를 모두 체크
- 단, 정렬을 통해 효율적으로 처리하고 있기 때문에 매우 빠르다 (O(n))
예시 분석
solution([[60, 50], [30, 70], [60, 30], [80, 40]])
- 정렬 → [[50, 60], [30, 70], [30, 60], [40, 80]]
- 가로 최댓값: max(50, 30, 30, 40) → 50
- 세로 최댓값: max(60, 70, 60, 80) → 80
- 결과: 50 * 80 = 4000