문제 핵심
sizes에 담겨 있을 때, 모든 명함을 넣을 수 있는 가장 작은 지갑의 넓이를 구하는 문제다. 명함은 회전할 수 있으므로, 각 명함마다 큰 값을 가로, 작은 값을 세로로 정리해서 생각하면 된다.즉, 각 명함을 다음 기준으로 통일한다.
작은 값 → 세로 후보
모든 명함을 이렇게 정리한 뒤, 가로 후보 중 최댓값과 세로 후보 중 최댓값을 곱하면 필요한 지갑의 최소 넓이를 구할 수 있다.
처음 접근
w와 세로 리스트 h에 값을 저장하는 방식으로 접근했다.접근 방향 자체는 맞았다. 다만 처음 코드에서는 append() 사용 방식과 append()의 위치에서 문제가 있었다.
처음 코드에서 틀린 점
def solution(sizes):
answer = 0
w = []
h = []
for i in range(len(sizes)):
if sizes[i][0]<sizes[i][1]:
sizes[i][0], sizes[i][1] = sizes[i][1], sizes[i][0]
w = w.append(sizes[i][0])
h = h.append(sizes[i][1])
answer = max(w) * max(h)
return answer
1. append()의 반환값을 다시 대입했다
처음 코드에서는 다음과 같이 작성했다.
w = w.append(sizes[i][0])
h = h.append(sizes[i][1])
하지만 append()는 리스트에 값을 추가하는 메서드일 뿐, 수정된 리스트를 반환하지 않는다. append()의 반환값은 None이므로, 위처럼 작성하면 w와 h가 None으로 바뀔 수 있다.
w = w.append(value)올바른 형태:
w.append(value)2. append()가 if문 안에 있었다
처음에는 append()가 if문 안에 있어서, 회전이 필요한 명함만 리스트에 저장되었다. 하지만 이미 가로가 세로보다 큰 명함도 지갑 크기 계산에 반드시 포함되어야 한다.
따라서 가로와 세로를 바꾸는 작업은 조건에 따라 수행하되, 리스트에 추가하는 작업은 모든 명함에 대해 실행되어야 한다.
w와 h에 추가해야 한다.개선 방향
먼저 append()를 대입 없이 사용하도록 수정했다. 그 다음 w.append()와 h.append()의 위치를 if문 밖으로 이동했다.
2. 첫 번째 값이 두 번째 값보다 작으면 두 값을 바꾼다.
3. 바꿨든 안 바꿨든 큰 값을
w에 넣고, 작은 값을 h에 넣는다.4.
max(w) * max(h)로 최종 지갑 넓이를 구한다.최종 풀이
def solution(sizes):
answer = 0
w = []
h = []
for i in range(len(sizes)):
if sizes[i][0] < sizes[i][1]:
sizes[i][0], sizes[i][1] = sizes[i][1], sizes[i][0]
w.append(sizes[i][0])
h.append(sizes[i][1])
answer = max(w) * max(h)
return answer
풀이 흐름
sizes[i][0]은 i번째 명함의 첫 번째 길이, sizes[i][1]은 두 번째 길이다. 두 값 중 첫 번째 값이 더 작다면 두 값을 교환해서 큰 값이 앞에 오도록 만들었다.
[30, 70] → [70, 30]이렇게 정리하면 모든 명함에서 앞쪽 값은 큰 길이, 뒤쪽 값은 작은 길이가 된다. 그 다음 큰 길이들 중 최댓값과 작은 길이들 중 최댓값을 구해 곱하면 지갑의 최소 넓이를 구할 수 있다.
max()와 min()으로도 표현할 수 있다. 중요한 것은 각 명함마다 큰 값과 작은 값을 같은 기준으로 분리하는 것이다.유사 유형 문제
sizes가 주어졌을 때, 각 명함을 회전할 수 있다고 가정하고 모든 명함을 담을 수 있는 최소 지갑의 둘레를 구하는 문제를 추가로 풀었다.유사 문제도 핵심 구조는 동일했다. 각 명함에서 큰 값과 작은 값을 정리한 뒤, 필요한 지갑의 가로와 세로를 구했다. 다만 마지막 계산이 넓이가 아니라 둘레라는 점이 달랐다.
유사 문제 풀이
def solution(sizes):
w = []
h = []
for i in range(len(sizes)):
if sizes[i][0] < sizes[i][1]:
sizes[i][0], sizes[i][1] = sizes[i][1], sizes[i][0]
w.append(sizes[i][0])
h.append(sizes[i][1])
answer = max(w) * 2 + max(h) * 2
return answer
원래 문제와 같은 점
두 문제 모두 2차원 리스트를 순회하면서 각 내부 리스트의 두 값을 비교하고, 필요하면 위치를 바꾸는 구조를 사용했다. 또한 정리된 가로 후보와 세로 후보를 각각 리스트에 저장하고 max()로 최종 크기를 계산했다.
append(), max() 사용이다.원래 문제와 다른 점
원래 문제에서는 지갑의 넓이를 구했기 때문에 max(w) * max(h)를 사용했다. 유사 문제에서는 지갑의 둘레를 구했기 때문에 max(w) * 2 + max(h) * 2를 사용했다.
max(w) * max(h)둘레 계산:
max(w) * 2 + max(h) * 2다만 이번 유사 문제는 마지막 계산식만 바뀐 성격이 강했다. 다음부터는 단순히 조건식이나 계산식만 바꾸는 문제보다, 같은 핵심 문법을 다른 상황에서 다시 쓰는 문제로 연습할 예정이다.
핵심 정리
명함은 회전할 수 있으므로 처음 주어진 가로와 세로를 그대로 사용할 필요가 없다. 각 명함에서 큰 값을 가로 후보로, 작은 값을 세로 후보로 모으면 모든 명함을 담을 수 있는 지갑 크기를 쉽게 계산할 수 있다.
또한 append()는 값을 추가하는 동작만 수행하고 반환값은 None이므로, w = w.append(...)처럼 대입하면 안 된다. 리스트에 값을 추가할 때는 w.append(...)처럼 단독으로 사용해야 한다.
사용한 핵심 문법 정리
sizes[i][0], sizes[i][1]처럼 리스트 안의 리스트에 접근할 때 사용했다.range(len(sizes))sizes의 인덱스를 0부터 마지막까지 순회하기 위해 사용했다.if 조건문sizes[i][0], sizes[i][1] = sizes[i][1], sizes[i][0] 형태로 임시 변수 없이 두 값을 바꿨다.append()append()는 반환값이 None이므로 대입해서 사용하면 안 된다.max()append()가 if문 안에 있으면 조건을 만족한 명함만 저장된다. 모든 명함을 저장하려면 append()를 if문 밖에 두어야 한다.'TIL > 코테' 카테고리의 다른 글
| [ Python ] 시저 암호 (0) | 2026.06.25 |
|---|---|
| [ SQL ] 아픈 동물 찾기 (0) | 2026.06.24 |
| [ Python ] 크기가 작은 부분문자열 (0) | 2026.06.23 |
| [ Python ] 삼총사 (0) | 2026.06.19 |
| [ Python ] 이상한 문자 만들기 (0) | 2026.06.18 |
