코딩테스트/백준
[백준 - 1654] 랜선 자르기 .java
머밍
2025. 5. 19. 19:37
https://www.acmicpc.net/problem/1654
- K개의 랜선을 잘라서 길이가 모두 같은 랜선 N개 이상 만들 수 있는 최대 길이 찾기
- 현재 길이로 잘라서 N개 이상 만들 수 있는지 판단
처음 이분 탐색으로 풀어야지 생각했지만 하나가 걸렸다
바로 현재 설정한 랜선 길이보다 더 짧은 랜선이 있을 경우 어떻게 되는가?였다
-> 답은 만들 수 없기에 0으로 누적된다
=> 더 짧은 랜선은 고려할 필요 없다
따라서 r의 최댓값은 입력 받을 수 있는 크기인 가장 긴 랜선 길이 -> 2^31-1보다 작거나 같은 자연수
int로 받으면 안되고 long 타입이여야함
1<<23
1 << n
-> 1을 왼쪽으로 n비트 밀기
-> 결과적으로 2ⁿ
but, 2³¹ → int 범위 초과 오버플로우 발생 (주의!)
나눗셈이 포함된 이진 탐색
=> mid가 0이 될 수 있는지를 항상 확인
=> l이 1부터 시작
import java.util.Arrays;
import java.util.Scanner;
public class Solution {
//현재 cut 길이로 랜선을 자를 때 n개 이상 만들 수 있는지 확인하는 함수
public static boolean isPossible(int[] len, long cut, int n) {
long count = 0;
for(int h : len) {
if(h>=cut) count += h/cut;
}
return count >=n;//목표 개수 이상이면 true
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int n = sc.nextInt();
int[] lens = new int[k];
for(int i =0; i<k; i++) {
lens[i] = sc.nextInt();
}
Arrays.sort(lens);
//l: 자를 수 있는 최소 길이 (0은 나눗셈 오류 생기므로 1부터)
long l = 1, r = (1<<31) -1,answer = 0;
while(l<=r) {
long mid = (l+r)/2;
//mid 길이로 잘랐을 때 n개 이상 만들 수 있다면 → 더 길게 자를 수 있는지 확인
if(isPossible(lens,mid,n)) {
answer = mid;//가능하니까 저장
l = mid+1;//그중 최댓값 찾아야함
} else r = mid-1;//더 짧게해야
}
System.out.print(answer);
}
}