[문제]
엘리트 학원은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 선생님은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm 은 버려야 한다. (이미 자른 랜선은 붙일 수 없다.)
편의를 위해 랜선을 자를때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수 길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.
▣ 입력설명
첫째 줄에는 엘리트학원이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그 후 K줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 2^31 - 1이하의 자연수로 주어진다.
▣ 출력설명
첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.
▣ 입력예제 1
4 11
802
743
457
539
▣ 출력예제 1
200
[풀이]
def Count(len):
cnt=0
for x in Line:
cnt+=(x//len)
return cnt
k, n=map(int, input().split())
Line=[]
res=0
largest=0
for i in range(k):
tmp=int(input())
Line.append(tmp)
largest=max(largest, tmp)
lt=1
rt=largest
while lt<=rt:
mid=(lt+rt)//2
if Count(mid)>=n:
res=mid
lt=mid+1
else:
rt=mid-1
print(res)
다른 풀이
k, n = map(int, input().split())
line = [int(input()) for _ in range(k)]
s, e = 1, max(line) # 이분 탐색의 처음과 끝 위치
while s <= e: # 적절한 랜선의 길이를 찾는 알고리즘
mid = (s+e) // 2
cnt = 0 # 랜선 수
for i in line:
cnt += i // mid # 분할 된 랜선 수
if cnt >= n: # 랜선의 개수가 분기점
s = mid + 1
else:
e = mid - 1
print(e)
[내용]
이 문제도 이분탐색으로 풀어야 한다는걸 아예 이해를 못했다....
이 문제는 매개 변수 탐색 으로, 이진 탐색을 이용해서 조건을 만족하는 최댓값을 구하는 문제 이다.
1. 문제에서 최종적으로 찾고자 하는 최솟값/최댓값을 매개변수로 본다.
2. 결정 함수를 정의하고 구현했을 때 결과 배열이 연속인지 확인한다.
3. 최솟값이면 결정함수의 결과가 [f,f, .... , t,t] 에서 f->t 로 바뀌는 부분을 찾는다.
4. 최댓값이면 결정 함수의 결과가 [t,t, ... , f,f] 에서 t->f로 바뀌는 부분을 찾는다
=> 매개 변수 탐색은 어떤 조건을 만족하는 위치 중에서 최댓값이나 최솟값을 찾을때 사용!
- "랜선의 길이" 가 매개변수가 됨.
<입력값 받는 방법>
line = [int(input()) for _ in range(k)]
위와 같이 받을 수도 있음!
'Coding Test > Python' 카테고리의 다른 글
| [Python] 마구간 정하기(결정알고리즘) (0) | 2023.02.17 |
|---|---|
| [Python] 뮤직비디오(결정알고리즘) (0) | 2023.02.16 |
| [python] 이분검색 (0) | 2023.02.13 |
| [Python] 봉우리 (0) | 2023.02.07 |
| [Python] 곳감(모래시계) (0) | 2023.02.06 |