차밍이
[Python] 백준 1654번 랜선 자르기 - 이분 탐색 본문
랜선 자르기 성공
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 128 MB | 38386 | 7504 | 4915 | 19.143% |
문제
집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.
이미 오영식은 자체적으로 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 줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는 231-1보다 작거나 같은 자연수이다.
출력
첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.
예제 입력 1 복사
4 11
802
743
457
539
예제 출력 1 복사
200
힌트
802cm 랜선에서 4개, 743cm 랜선에서 3개, 457cm 랜선에서 2개, 539cm 랜선에서 2개를 잘라내 모두 11개를 만들 수 있다.
소스코드
from sys import stdin
K, N = map(int,stdin.readline().split())
li = list(map(int,stdin.readlines()))
h, l = sum(li)//N, 1
# h, l = max(li), 1
while l <= h :
mid = (h+l)//2
cnt = sum([x//mid for x in li])
if cnt < N:
h = mid - 1
elif cnt >= N:
l = mid + 1
ans = mid
print(ans)
- 결과
- 메모리 : 29284 KB
- 시간 : 72 ms
- 문제 풀이
- 필요한 랜선의 갯수는 N개입니다. N개의 랜선을 만들 수 있으면서 가장 긴 길이의 랜선의 길이를 찾는 문제입니다.
- 숫자가 커지면 그냥 1씩 키우고 줄이면서 개수를 세어서는 시간 초과를 피할 수 없습니다.
- 이분 탐색을 통해서 빠르게 원하는 값을 찾아가는 것이 효율적입니다.
high와 low로
가장 긴 길이와 가장 작은 길이를 구한 후, 이분 탐색을 통해서 점점 필요한 길이를 찾아나가도록 합니다.max(li)
를high
값으로 놓고 푸는 것에 대해서 이해가 되면, 조금만 더 생각하면sum(li)//N
으로 놓았는지 이해가 될 것입니다. 사실 전체 길이에서 기존의 랜선을 자르고 남은 길이는 재사용할 수 없기 때문에 전체 길이에서 N개로 나눈 값만큼의 길이보다 줄어들 것입니다. 그럼에도 저렇게 놓은 이유는 이분 탐색할 범위를 줄이기 위해서입니다.- 참고로 입력되는 랜선의 개수(K) 값이 많아지면 입력받아야 하는 값들의 수도 많아집니다. 그러면
input()
을 통해서 입력받는 것보다는sys.stdin.readline()
을 통해서 system input으로 입력받는 것과의 시간 차이가 상당히 많이 납니다.
- 유사한 문제
'파이썬 > 알고리즘' 카테고리의 다른 글
[파이썬] 백준 2178번 미로 탐색 - BFS 최단 경로 탐색 (2) | 2020.03.13 |
---|---|
[파이썬] 백준 2667번 단지번호붙이기 - DFS 방식 문제 풀이 (0) | 2020.03.08 |
[파이썬] 백준 2606번 바이러스 - BFS방식과 DFS 방식 비교 (0) | 2020.03.07 |
[파이썬] 백준 1260번 DFS와 BFS (4) | 2020.03.07 |
[Python] 백준 4195번 친구 네트워크 - 유니온 파인드(Union Find) 활용 (0) | 2020.02.29 |
[파이썬] 백준 5397번 키로거 - 스택 발상의 전환 (1) | 2020.02.29 |
[Python] 백준 10816번 숫자 카드 2 - 다양한 풀이 이분탐색, 해시, Counter (2) | 2020.02.27 |
[Python] 백준 1920번 수 찾기 - 두가지 풀이:이분탐색과 자료형 (1) | 2020.02.27 |