문제
집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.
이미 오영식은 자체적으로 K개으 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm짜리 랜선을 두개 잘라내면 20cm는 버려야 한다. (이미 자른 랜선은 붙일 수 없다)
편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 떄는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이떄 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오
풀이
해당 문제는 이진 탐색을 사용하는데 여기서 문제는 주어진 배열에서 값을 찾는 것이 아니기 때문에 정렬이 필요없다. 하지만 배열에 값들을 이용해야 하기 떄문에 가장 큰 값은 찾아야 한다. 1부터 해당 제일 큰 값으로 조회를 해야한다 원래는 0으로 해도 되지만 해당 문제는 결국 랜선을 자르는 걸 나누기로 표현하고 나머지는 모두 버려도 된다는 표현이다.
그래서 만약 0일 경우 에러가 나서 1로 바꾸고 진행해야한다. 1부터 제일 큰 값까지 (left <= right)를 통해 비교를 해나가면
된다. while문 안에서 mid를 구해서 해당 mid를 통해 각 배열을 나눈 값들을 모두 더한 count 값을 통해 N과 비교한다. 만약 N이 더 클 경우 랜선의 기준선이 너무 크기 때문에 right를 왼쪽으로 떙겨서 다시 진행하면 된다.
마지막 출력은 right를 한다. left는 while 조건 자체가 right보다 커야하기 떄문에 그렇다
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int K = Integer.parseInt(st.nextToken());
int N = Integer.parseInt(st.nextToken());
int arr[] = new int[K];
long right = 0;
for (int i = 0; i < K ; i++) {
arr[i] = Integer.parseInt(br.readLine());
right = Math.max(right,arr[i]);
}
long left = 1;
while(left <= right){
long mid = (left + right)/2;
int count = 0;
for(int m : arr){
count += (m/mid);
}
if(count >= N){
left = mid+1;
}else {
right = mid-1;
}
}
System.out.println(right);
}
}
'알고리즘' 카테고리의 다른 글
백준 No.10815 숫자카드- JAVA (0) | 2023.04.03 |
---|---|
백준 No.6236 용돈 관리- JAVA (0) | 2023.04.01 |
백준 No.2805 나무자르기 - JAVA (0) | 2023.03.29 |
프로그래머스 Lv.2 순위검색-JAVA (0) | 2023.03.29 |
프로그래머스 Lv.2 뒤에 있는 큰 수 찾기-JAVA (0) | 2023.03.26 |