알고리즘 - 이분탐색 (1654)

heyhey·2023년 1월 9일
0

알고리즘

목록 보기
1/9

1654 랜선 자르기

문제

집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.

이미 오영식은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm는 버려야 한다. (이미 자른 랜선은 붙일 수 없다.)

편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.


6개월만에 알고리즘 문제를 접했다..
input값 받아오는 법은 어떻게 했더라..
Min,max 도 기억이 안나서 찾아보면서 풀었다...
각설하고, 문제 풀이 갑니다

최초 풀이

K,N = map(int,input().split())
ropeList = []
for i in range(K):
  ropeList.append(int(input()))

biggest_number = biggest_number =sum(ropeList)//N 
# 가장큰 값을 정해서 1씩 빼면서 가장 큰 값을 찾아내겠다 
# 그래도 그 값은 전체 리스트를 N개로 나눈 값에서 부터 시작한다.
while True:
	result = 0
	for rope in ropeList:
		result += rope//biggest_number
	if result == N:
		print(biggest_number)
		break
	biggest_number-=1

너무 쉽게 풀릴 것 같아서 될리가 없다고 생각했다
역시 시간초과

전체를 조회할 때 시간을 절약하는 방법은 이분탐색이다.
이분탐색 == up down 이랑 똑같다고 생각해보자

  1. 1~ 99 번 중에서 하나의 값을 찾을 때
  2. 중간 수 50을 찍는다. => up
  3. 남은 수는 51~99 중에 있다 => 75 => up
  4. 이런식으로 진행하면 시간을 많이 절약할 수 있다.

다시 풀어보자

start = 1
end = max(ropeList)

def midNumber():
  return (start+end)//2

def get_sum_rope():
  result = 0
  for rope in ropeList:
    result += rope//mid
  return result

while start<=end:
  mid = midNumber()
  ropes = get_sum_rope()
  if ropes >= N:
    start = mid+1
  elif ropes< N:
    end = mid-1

print(end)
  1. 첫 값과 끝 값을 두고 만일 첫 값이 끝값과 같거나 커져버리면 끝내버린다.
  2. 중간 자리 mid 를 골라 그 값이 우리가 원하는 값보다 크면 시작값을 높이고, 낮다면 끝값을 낮춘다.
profile
주경야독

0개의 댓글