알고리즘/백준
1654번 : 랜선 자르기
코딍코딍
2022. 8. 5. 18:30
https://www.acmicpc.net/problem/1654
1654번: 랜선 자르기
첫째 줄에는 오영식이 이미 가지고 있는 랜선의 개수 K, 그리고 필요한 랜선의 개수 N이 입력된다. K는 1이상 10,000이하의 정수이고, N은 1이상 1,000,000이하의 정수이다. 그리고 항상 K ≦ N 이다. 그
www.acmicpc.net
문제
코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int k = Integer.parseInt(st.nextToken()); //갖고 있는 랜선의 수
int n = Integer.parseInt(st.nextToken()); //필요한 랜선의 수
int ran[] = new int[k];
//랜선 입력받기
for(int i=0;i<k;i++) ran[i] = Integer.parseInt(br.readLine());
long result=0;
long start=0;
long end = Arrays.stream(ran).max().getAsInt();
//이진탐색 기준: 랜선의 수, 이진탐색의 범위: 랜선의 길이
while(start<=end) {
long mid = (start+end)/2; //랜선 길이
if(mid==0) mid=1;
long count=0;
for(int i=0;i<k;i++) {
count+=ran[i]/mid;
}
//랜선의 수가 부족하다면 랜선의 길이 줄이기
if(count<n) end=mid-1;
//랜선의 수가 충분하다면 랜선의 길이 최대한 늘려보기
else {
result = mid;
start=mid+1;
}
}
System.out.println(result);
}
}
해결방법
처음 코드를 구현할 때 랜선의 수를 기준으로 이진 탐색을 수행하였다. 테스트 케이스는 통과했지만 제출해보니 "틀렸습니다."다 떴다. 이유는 범위가 int형의 범위를 초과할 수 있으므로 long형으로 수정해줘야 했다. 수정하여 제출했는데 또 "런타임 에러(ArithmeticException)"가 떴다. 이유는 start:0, end:1 일 경우 mid값이 0이되어 랜선의 수를 구할 때 값을 0으로 나누는 계산을 하기에 예외가 발생하는 것이다. 이를 해결하기위해 if(mid==0) mid=1; 을 추가적으로 작성하였다.