미숙한 블로그 주인이 코딩테스트 문제를 풀어가는 과정을 담은 글입니다. 이 풀이가 효율적인 풀이가 아닐 수 있으며, 부정확한 정보가 많이 있을 수 있습니다. 보완해야할 점이 있다면 댓글로 남겨주세요!
https://www.acmicpc.net/problem/1654
랜선 자르기
문제
문제
집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 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줄에 걸쳐 이미 가지고 있는 각 랜선의 길이가 센티미터 단위의 정수로 입력된다. 랜선의 길이는 2^(31)-1보다 작거나 같은 자연수이다.
출력
첫째 줄에 N개를 만들 수 있는 랜선의 최대 길이를 센티미터 단위의 정수로 출력한다.
풀이
이분 탐색의 응용인 Parametric Search를 시도해보는 문제였다.
1부터 2^(31)-1까지 수를 하나하나 비교해보면서 답을 구할 수도 있겠지만, 시간 초과로 인해 통과할 수 있는 풀이는 아니다.
그렇다면 이분 탐색은 어떻게 진행할까.
우선 low = 1로, high = 보유한 랜선의 최대길이로 지정해준다.보유한 랜선보다 더 길게는 자를 수 없기 때문에 high는 보유한 랜선 중에서 최대 길이가 된다.이렇게 해서 mid의 값을 구할 수 있는데, 이 mid의 값이 우리가 찾고자 하는 N개를 만들 수 있는 랜선의 최대 길이이다.
이제 mid의 값을 변경하는 기준을 지정해줘야한다.그 기준은 mid의 길이로 보유한 랜선들을 잘라서 나온 랜선의 개수이다.
만약, mid로 잘랐을 때 N보다 크거나 같은 수가 나왔다면, 자르는 크기를 더 늘려줘도 되므로 low를 갱신해준다.같은 수도 같이 갱신하는 이유는, 랜선의 최대 길이를 구하기 때문이다.100cm로 10개가 나오고 110cm로도 10개가 나오면 답은 110cm가 되기 때문이다.
반대로 mid로 잘랐을 때 N보다 작다면, 자르는 크기를 더 줄여야 하므로 high를 갱신해준다.이렇게 해서 최종적으로 구한 mid가 구하고자하는 랜선의 최대 길이가 된다.
#include <iostream>
#include <vector>
using namespace std;
int main() {
int K, N;
cin >> K >> N;
vector<int> lan(K);
int max_len = 0;
for (int i = 0; i < K; i++) {
cin >> lan[i];
max_len = max(max_len, lan[i]);
}
long long left = 1;
long long right = max_len;
long long mid = (left + right) / 2;
while (left <= right) {
int count = 0;
for (int i = 0; i < K; i++) {
count += lan[i] / mid;
}
if (count >= N) {
left = mid + 1;
}
else {
right = mid - 1;
}
mid = (left + right) / 2;
}
cout << mid << endl;
return 0;
}
'코딩 테스트(Coding test) > BOJ' 카테고리의 다른 글
[BOJ 2580번/C++] 스도쿠 (0) | 2022.10.18 |
---|---|
[BOJ 2178번/C++] 미로 탐색 (1) | 2022.10.15 |
[BOJ 1012번/C++] 유기농 배추 (0) | 2022.10.13 |
[BOJ 9663번/C++] N-Queen (0) | 2022.10.12 |
[BOJ 2667번/C++] 단지번호붙이기 (0) | 2022.10.09 |