Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 스터디
- peft
- Coursera
- 판다스
- Lora
- 데이터분석
- 코딩테스트실력진단
- English
- 그래프이론
- 코드트리
- Study
- 코딩테스트
- speaking
- paper review
- Scaling Laws
- 프로그래머스
- 플로이드와샬
- 파인튜닝
- Fine-Tuning
- DP
- 완전탐색
- 최단경로
- 이분탐색
- 파이썬
- Python
- bfs/dfs
- 알고리즘
- Generative AI
- LLM
- 머신러닝
Archives
- Today
- Total
생각하는 아져씨
[Programmers] 최소직사각형 본문
최소직사각형
https://school.programmers.co.kr/learn/courses/30/lessons/86491
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 정의
다양한 모양/크기의 명함을 모두 수납할 수 있는 지갑을 만들어야 한다. 모든 명함의 가로 길이와 세로 길이가 2차원 배열(sizes)로 주어지면 모든 명함을 수납할 수 있는 가장 작은 사이즈의 지갑을 return 해야 한다.
주의할 점: 지갑을 가로 또는 세로로 눕혀서 수납할 수도 있음. → 지갑의 가로와 세로 길이를 바꿔 계산할 수 있음.
접근 방법
이 문제는 단순히 (가로의 최댓값) * (세로의 최댓값) 을 구해서 지갑의 크기를 구하는 문제가 아니다.
모든 명함의 가로 길이를 포함하면서 세로 길이도 충족하게 끔 지갑의 사이즈를 정해야 한다.
이 문제의 핵심은 지갑을 가로로 눕힐 수 있다는 점이다. 이 점을 고려해 지갑의 (가로, 세로)를 정하면 된다.
- 첫번재 접근
- 구현이라고 생각하고 명함을 포함할 수 있는 모든 지갑의 크기를 다 구하고, 그 중에서 가장 작은 사이즈의 지갑을 리턴하려고 했다. → 잘못된 접근
- 두번째 접근
- 첫번째 접근의 풀이가 잘못됐음을 알고 모범답안을 살펴보았다.
- 지갑의 가로길이는 명함의 모든 가로를 포함하면되고, 지갑의 세로 길이는 명함의 모든 세로 길이를 포함하면 된다는 사실을 다시 본다면?
- 👉 명함의(가로-세로) 중 큰 것은 가로(또는 세로)로, 작은 것은 세로(또는 가로)로 설정하고, 이 둘의 곱을 구하면 된다.
문제 해설
- (가로, 세로) 중 큰 값은 가로로, 작은 값은 세로로 취급한다.
- 가로 리스트 중 가장 큰 값 * 세로 리스트 중 가장 큰 값 을 구하면 된다.
풀이
1. 올바른 풀이
# 모든 명함을 수납할 수 있는 가장 작은 지갑
def solution(sizes):
answer = 0
max_w, max_h = [], []
for s in sizes:
if s[0] > s[1]:
max_w.append(s[0])
max_h.append(s[1])
else:
max_h.append(s[0])
max_w.append(s[1])
answer = max(max_w) * max(max_h)
return answer
2. 첫번째 접근(잘못된 풀이)
- 일단 주어진 sizes 에서 가로 최댓값 * 세로 최댓값을 구하고
- 큰 값을 기준으로 가로와 세로의 위치를 하나씩 바꿔보면서 구해진 지갑 사이즈와 비교했다.
- 구해진 지갑 사이즈 > 가로-세로를 바꿔서 계산된 사이즈이면 → 지갑 사이즈를 업데이트 했다.
- 가로-세로가 변경될 수 있는 숫자가 꼭 큰 숫자만은 아니었다. 나의 착각이었다.
# 모든 명함을 수납할 수 있는 가장 작은 지갑
import copy
def max_size(size_list):
max_width = size_list[0][0]
max_height = size_list[0][1]
for s in size_list:
max_width = max(max_width, s[0])
max_height = max(max_height, s[1])
return max_width, max_height
def solution(sizes):
answer = 0
# 일단 가로 max, 세로 max를 구해서 지갑 크기를 구한다.
max_w, max_h = max_size(sizes)
answer = max_w * max_h # 가장 큰 가로, 세로 길이일 때 지갑 크기
# 가로를 세로로 바꿔보기
tmp_sizes = copy.deepcopy(sizes)
for s in tmp_sizes:
if max_w == s[0]:
tmp = s[1]
s[1] = s[0]
s[0] = tmp
tmp_mw, tmp_mh = max_size(tmp_sizes)
answer = min(answer, (tmp_mw*tmp_mh))
# 세로를 가로로 바꿔보기
tmp_sizes = copy.deepcopy(sizes)
print(tmp_sizes)
for s in tmp_sizes:
if max_h == s[1]:
tmp = s[0]
s[0] = s[1]
s[1] = tmp
tmp_mw, tmp_mh = max_size(tmp_sizes)
answer = min(answer, (tmp_mw*tmp_mh))
return answer
정리
- 구현이라고 해서 하나씩 다 구해보는 문제라고 생각하고 접근했는데 그게 아니었다.
- 아이디어가 필요한 문제였다.
- 시간 복잡도는 sizes만큼 돌면되므로, $O(N)$
'Study > Algorithm' 카테고리의 다른 글
[BOJ] 13458번 - 시험감독 (0) | 2023.03.25 |
---|---|
[BOJ] 1157번 - 단어공부 (0) | 2023.03.25 |
[BOJ] 2979번 - 트럭주차 (0) | 2023.03.24 |
[BOJ] 11724번 - 연결 요소의 개수 (0) | 2023.02.16 |
[BOJ] 1012번 - 유기농 배추 (0) | 2023.02.14 |