(JAVA) BOJ 백준 1654 LAN 케이블 절단

https://www.acmicpc.net/problem/1654

1654호: LAN 케이블 절단

첫 번째 줄에 Yingzhi Wu가 이미 소유하고 있는 K LAN 케이블과 그가 필요로 하는 N LAN 케이블을 입력합니다.

K는 1~10,000의 정수이고, N은 1~1,000,000의 정수이다.

그리고 항상 K ≤ N입니다.

저것

www.acmicpc.net

질문

집에서 시간을 때우던 오영식은 박성원의 전화를 받았다.

박성원은 캠프를 위해 N LAN 케이블을 만들고 싶지만 너무 바빠서 영식에게 도움을 요청할 수 없습니다.

오영식은 이미 자체 K랜선을 갖고 있다.

그러나 K LAN 케이블은 길이가 같지 않습니다.

박성원은 N LAN선을 같은 길이로 만들고 싶어서 K LAN선으로 잘라야 했다.

예를 들어 300cm LAN 케이블에서 140cm LAN 케이블 2개를 자르면 20cm는 버려야 합니다.

(절단된 LAN 케이블은 연결할 수 없습니다.

)

편의상 LAN 케이블을 자르거나 만들 때 길이 손실이 없다고 가정하고, 기존의 K LAN 케이블로 N LAN 케이블을 만들 수 없는 상황은 없다고 가정합니다.

절단할 때 항상 센티미터 단위의 정수 길이로 절단한다고 가정해 봅시다.

N 이상 만들기는 N 만들기에 포함됩니다.

이때 만들 수 있는 네트워크 케이블의 최대 길이를 구하는 프로그램을 작성하시오.

입력하다

첫 번째 줄에 Yingzhi Wu가 이미 소유하고 있는 K LAN 케이블과 그가 필요로 하는 N LAN 케이블을 입력합니다.

K는 1~10,000의 정수이고, N은 1~1,000,000의 정수이다.

그리고 항상 K ≤ N입니다.

그런 다음 이미 K를 초과하는 각 LAN 회선 길이에 대해 센티미터 단위로 정수를 입력합니다.

LAN 케이블의 길이는 231-1 이하의 자연수입니다.

전체 코드

import java.util.*;
import java.io.*;

public class Main {
	static long() lan;
	static int K, N;
	public static void main(String() args) throws Exception {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(bf.readLine(), " ");
		K = Integer.parseInt(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		lan = new long(K);
		long max = 0;
		for(int i=0; i<K; i++) {
			lan(i) = Integer.parseInt(bf.readLine());
			max = Math.max(max, lan(i));
		}
		find(0, max);
	}
	static void find(long start, long end) {
		long min = start; long max = end;
		while(min <= max) {
			long mid = (min+max) / 2;
			if(cut(mid)) min = mid+1;
			else max = mid -1;
		}
		System.out.println(min-1);
	}
	static boolean cut(long h) {
		if(h == 0) return true;
		long count = 0;
		for(int i=0; i<K; i++)
			count += (lan(i) / h);
		if(count >= N) return true;
		else return false;
	}
}

이진 검색에서 중요한 부분은 while의 조건과 시작과 끝의 업데이트 및 업데이트 조건입니다.


이 질문의 정답 길이는 N을 LAN 회선 수로 만드는 길이입니다.


따라서 조건은 숫자가 N(보다 작음) 또는 (크거나 같음) 두 가지 경우로 나누어야 합니다.


while의 조건은 min≤max로 설정되어 있으므로 while이 끝나면 min=max+1의 형태가 된다.


정답인 Mid는 else 조건에 의해 mid-1로 변경되므로 결과 값은 결국 max 또는 min-1이 출력되어야 합니다.


while(min < max)의 경우 두 값이 같으면 while이 종료된다.

이 경우 무한 루프가 발생할 수 있습니다.

이때 h가 0인 경우에 주의!
LAN 회선의 길이가 1이면 h가 0인지 조사합니다.

따라서 0이 들어오면 true를 지정하십시오!
(사실 0은 답이 아니므로 거짓으로 느껴지실 것입니다.

다만 참과 거짓은 가능한 답이 아니라 mid의 증감으로 계산해야 합니다.

)