실전문제
부품 찾기
동빈이네 전자 매장에는 부품이 N개 있다. 각 부품은 정수 형태의 고유한 번호가 있다.
어느 날 손님이 M개 종류의 부품을 대량으로 구매하겠다며 당일 날 견적서를 요청했다.
동빈이는 때를 놓치지 않고 손님이 문의한 부품 M개 종류를 모두 확인해서 견적서를 작성해야 한다.
이때 가게 안에 부품이 모두 있는지 확인하는 프로그램을 작성해보자.
- 나의 풀이
N = int(input())
all = list(map(int,input().split()))
M = int(input())
find = list(map(int,input().split()))
def binary_search(array, target, start, end):
while start <= end:
mid = (start + end) // 2
# 찾은 경우 중간점 인덱스 반환
if array [mid] == target:
return mid
# 중간점의 값보다 착고자 하는 값이 작은 경우 왼쪽 확인
elif array[mid] > target:
end = mid - 1
# 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인
else:
start = mid + 1
return None
for i in find:
result = binary_search(sorted(all), i, 0, N - 1)
if result == None:
print('no',end=' ')
else:
print('yes',end=' ')
- 답안 예시 코드(이진 탐색)와 95% 일치한다.
- 이진 탐색이 아닌 방법으로 푸는 예시가 더 직관적인 것 같다.
- 답안 예시 코드(계수 정렬)
# N(가게의 부품 개수)을 입력받기
n = int(input())
array = [0] * 1000001
# 가게에 있는 전체 부품 번호를 입력받아서 기록
for i in input().split():
array[int(i)] = 1
# M(손님이 확인 요청한 부품 개수)을 입력받기
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백으로 구분하여 입력
x = list(map(int, input().split()))
# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
# 해당 부품이 존재하는지 확인
if array[i] == 1 :
print('yes', end=' ')
else:
print('no', end=' ')
- 답안 예시 코드(집합 자료형 이용)
# N(가게의 부품 개수)을 입력받기
n = int(input())
# 가게에 있는 전체 부품 번호를 입력받아서 집합(set) 자료형에 기록
array = set(map(int, input().split()))
# M(손님이 확인 요청한 부품 개수)을 입력받기
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백으로 구분하여 입력
x = list(map(int, input().split()))
# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
# 해당 부품이 존재하는지 확인
if i in array:
print('yes', end=' ')
else:
print('no', end=' ')
떡볶이 떡 만들기
오늘 동빈이는 여행 가신 부모님을 대신해서 떡집 일을 하기로 했다. 오늘은 떡볶이 떡을 만드는 날이다.
동빈이네 떡볶이 떡은 재밌게도 떡볶이 떡의 길이가 일정하지 않다. 대신에 한 봉지 안에 들어가는 떡의 총 길이는 절단기로 잘라서 맞춰준다.
절단기에 높이(H)를 지정하면 줄지어진 떡을 한 번에 절단한다. 높이가 H보다 긴 떡은 H 위의 부분이 잘릴 것이고, 낮은 떡은 잘리지 않는다.
예를 들어 높이가 19, 14, 10, 17cm인 떡이 나란히 있고 절단기 높이를 15cm로 지정하면 자른 뒤 떡의 높이는 15, 14, 10, 15cm가 될 것이다. 잘린 떡의 길이는 차례대로 4, 0, 0, 2cm이다. 손님은 6cm만큼의 길이를 가져간다.
손님이 왔을 때 요청한 총 길이가 M일 때 적어도 M만큼의 떡을 얻기 위해 절단기에 설정할 수 있는 높이의 최댓값을 구하는 프로그램을 작성하시오.
- 나의 풀이
n, m = map(int,input().split())
dduk = list(map(int,input().split()))
array = list(range(max(dduk)))
def binary_search(array, dduk, m, start, end):
result = 0
while start <= end:
mid = (start + end) // 2
total = sum([i-mid if i>mid else 0 for i in dduk])
if total < m:
end = mid - 1
else:
result = mid
start = mid + 1
return result
print(binary_search(array, dduk, m, 0, max(dduk)))
- 처음에는 풀이와 다르게 if 조건에서 '적어도'라는 조건을 생각하지 않고 기본적인 이진탐색 코드처럼 구현함
- 나의 풀이에서는 굳이 저장하지 않아도 되는 array를 추가로 저장함
- 함수 대신 바로 while문으로 구현하는게 더 간결함
- 답안 예시 코드
# 떡의 개수(N)와 요청한 떡의 길이(M)을 입력받기
n, m = list(map(int, input().split()))
# 각 떡의 개별 높이 정보를 입력받기
array = list(map(int, input().split()))
# 이진 탐색을 위한 시작점과 끝점 설정
start = 0
end = max(array)
# 이진 탐색 수행(반복적)
resuIt = 0
while(start <= end):
total = 0
mid = (start + end) // 2
for x in array: # 잘랐을 때의 떡의 양 계산
if x > mid:
total += x - mid
# 떡의 양이 부족한 경우 더 많이 자르기(왼쪽 부분 탐색)
if total < m:
end = mid - 1
# 떡의 양이 충분한 경우 덜 자르기(오른쪽 부분 탐색)
else:
result = mid # 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록
start = mid + 1
# 정답 출력
print(result)
Reference
'Coder > 알고리즘' 카테고리의 다른 글
이코테 CHAPTER 03 그리디 실전 문제 (0) | 2022.03.05 |
---|---|
이코테 CHAPTER 03 그리디 정리 및 실전 문제(큰 수의 법칙) (0) | 2022.02.23 |
이코테 CHAPTER 07 이진 탐색 정리 (0) | 2022.02.14 |
이코테 CHAPTER 06 정렬 실전 문제 (0) | 2022.02.14 |
이코테 CHAPTER 06 정렬 + 실전 문제(위에서 아래로) (0) | 2022.02.07 |