문제
집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 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개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.
문제 접근 방법
브루트 포스 알고리즘으로 코드를 작성하기에는 입력의 범위가 너무 광범위해서 최악의 경우 연산 시간이 꽤 오래 걸려 무조건 문제 조건 시간 내 연산이 불가능할 것이 뻔하다.
따라서 보다 효율적으로 랜선의 최대 길이를 구해야 하는데 그래서 내가 선택한 방법은 이분 탐색(BinarySearch)이다.
max = 가장 긴 랜선의 길이+1, min = 0으로 두고 이분 탐색을 진행해준다.
이때, 탐색하는 숫자의 범위의 선택 기준은 랜선의 개수 n이다.
n개보다 랜선이 조금 나오면 mid~min 범위를 선택해주고,
n개보다 랜선이 많이 나오면 max~mid 범위를 선택해준다.
이때, n개만큼 랜선이 나온다고 탐색을 종료할 것이 아니라 n개를 만들 수 있는 최대의 길이를 구하라 하였으므로 범위가 1이 될 때까지 계속 탐색을 진행해준다. 따라서,
n개의 랜선이 나오면 max~mid사이의 범위를 선택해서 계속 탐색해주면 된다.
그렇게 구한 수를 출력해주면 문제는 해결된다.
JAVA 코드 풀이
코드 실행 결과
후기
처음 브루트 포스 알고리즘으로 해결하려다가 시간 초과에 걸려서 테스트 케이스를 줄일 방법으로 이분 탐색을 생각해서 문제를 해결했다. 찾아야 할 수를 알고 있다면 Arrays.binarysearch() 함수를 이용하면 됐겠지만, 그렇지 않기 때문에 내가 직접 코드를 작성하여 어떤 수를 찾아야 하는지 알아야 한다.
문제 원본
'문제 풀이 > [JAVA_자바] 백준' 카테고리의 다른 글
[JAVA / 자바] 백준 2178번 - 미로 탐색 (0) | 2022.02.03 |
---|---|
[JAVA / 자바] 백준 1003번 - 피보나치 함수 (0) | 2022.02.02 |
[JAVA / 자바] 백준 1260번 - DFS와 BFS (0) | 2022.01.31 |
[JAVA / 자바] 백준 1463번 - 1로 만들기 (0) | 2022.01.28 |
[JAVA / 자바] 백준 10989번 - 수 정렬하기 3 (0) | 2022.01.27 |