문제풀이/일일연습문제

[Brute Force]99클럽 코테 스터디 16일차 TIL + 프로그래머스/1/86491. 최소직사각형

Mo_bi!e 2024. 8. 7. 09:04

문제 설명

명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.

아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.

명함 번호 가로 길이 세로 길이
1 60 50
2 30 70
3 60 30
4 80 40

가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.

모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.


제한사항
  • sizes의 길이는 1 이상 10,000 이하입니다.
    • sizes의 원소는 [w, h] 형식입니다.
    • w는 명함의 가로 길이를 나타냅니다.
    • h는 명함의 세로 길이를 나타냅니다.
    • w와 h는 1 이상 1,000 이하인 자연수입니다.

입출력 예
sizes result
[[60, 50], [30, 70], [60, 30], [80, 40]] 4000
[[10, 7], [12, 3], [8, 15], [14, 7], [5, 15]] 120
[[14, 4], [19, 6], [6, 16], [18, 7], [7, 11]] 133

입출력 예 설명

입출력 예 #1
문제 예시와 같습니다.

입출력 예 #2
명함들을 적절히 회전시켜 겹쳤을 때, 3번째 명함(가로: 8, 세로: 15)이 다른 모든 명함보다 크기가 큽니다. 따라서 지갑의 크기는 3번째 명함의 크기와 같으며, 120(=8 x 15)을 return 합니다.

입출력 예 #3
명함들을 적절히 회전시켜 겹쳤을 때, 모든 명함을 포함하는 가장 작은 지갑의 크기는 133(=19 x 7)입니다.

 

 

<내코드> : 16분 29초

def solution(sizes):
    big, small = [], []
    
    for size in sizes:
        # for i in range(len(size)): # 이 부분 필요가 전혀 없음
            big.append(max(size))
            small.append(min(size))
    
    # 큰값과 작은 값 각각 도출하기
    bob = max(big)
    sob = max(small)
    return bob * sob

1. 어제와 비교

- 오늘은 어제와 비교해서 itertools.cycle()이나, zip 등이 특별하게 쓰여진건 없음

다만 리스트 comprehension을 이용하면 좀 더 갈끔하게 가능할것으로 판단이 됨

 

2. 헤맨부분

- 실수로 이중반복문을 굳이 넣어서 사용함

=> 리스트 안에 인덱스가 0,1 인 리스트를 순환적으로 추출하기 위해서 만들었음, 하지만 max(), min() 메소드 하나로 충분히 해결이 가능함

<모범사례>

def solution(sizes):
    # 모든 명함을 수납하기 위해 명함의 가로와 세로 길이 중 큰 값을 첫 번째 요소로, 작은 값을 두 번째 요소로 정렬합니다.
    sizes = [(max(size), min(size)) for size in sizes]
    
    # 가장 큰 가로 길이와 가장 큰 세로 길이를 각각 구합니다.
    max_width = max(size[0] for size in sizes)
    max_height = max(size[1] for size in sizes)
    
    # 지갑의 크기는 가장 큰 가로 길이와 가장 큰 세로 길이를 곱한 값입니다.
    return max_width * max_height

- 리스트 컴프리헨션을 적극적으로 이용함

=> 아직 문제를 풀면서 컴프리헨션을 이용해야겠다는 아이디어를 생각못함

 

 

<보충학습>

1. 연습문제 풀기

- 튜플 언패킹문제와 리스트컴프리헨션

# 튜플 언패킹
# .1 다음과 같은 리스트가 주어집니다. 이 리스트는 여러 학생의 이름과 나이를 포함하고 있습니다. 튜플 언패킹을 사용하여 각 학생의 이름과 나이를 출력하세요.
students = [("Alice", 21), ("Bob", 22), ("Charlie", 23), ("David", 24)]

for n , a in students:
    print(n ,a)

# 2. 리스트 컴프리헨션을 이용한 최적화된 가방 크기 계산
books = [[20, 30], [10, 40], [25, 15], [35, 25]]

# max등은 2개이상의 요소를 무조건 주어야함
bag = [(max(w,h), min(w,h)) for w, h in books]

max_w = max(book[0] for book in bag)
max_h = max(book[1] for book in bag)

result =  max_w * max_h
print(result)

# 3. 가장 큰 값 구하기 - 주차장
cars = [[4, 2], [5, 3], [6, 4], [3, 3]]

lot = [[max(w,h), min(w,h)] for w, h in cars]

max_lot = max(car[0] for car in lot)
min_lot = max(car[1] for car in lot)

result = max_lot * min_lot

print(result)