点击查看代码
/*
木棒切割问题:
给定N根(<1000)木棒及其长度,至少要将它们切割成K段相等长度的木棒,求木棒最长的切割长度L(L是整数)
例如给出三根长度分别是10、24、15的木棒,至少将它们切割成7段长度相等的木棒,可以得到的最大长度为6
输入样例;
3 7
10 24 15
输出样例:
6
解题思路:
如果L越长,每根木棒可以切割的段数s就越少。设当前长度是L1,每根木棒可以切割的段数是s1,总段数是count。
因为L1增大,count就减少,问题就变成求解最后一个满足于“count>=K”时的长度L1,此时L1就是最大长度
因此可以变成求解第一个满足于“count<K“时的长度L1,得到L1后,使L1减一就得到最大长度L
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996)
int main(){
int N, K, a[1000]; //最多输入1000根木棒长度
scanf("%d%d", &N, &K); //读取木棒数量,要切割的数量
for (int i = 0; i < N; i++)
{
scanf("%d", &a[i]); //读取每根木棒长度
}
sort(a, a + N); //对木棒长度升序排序,二分查找前提是对有序序列进行二分查找
//木棒最短长度为0,最长为a[n-1],区间[left,right]=[0,a[n-1]]
int left = 0, right = a[N - 1], mid;
while (left < right) //left==right时找到第一个使count<K的L1
{
int count = 0; //在当前长度L1下,可以切割的木棒总数
mid = left + (right - left) / 2; //当前长度L1
for (int i = 0; i < N; i++) {
count += a[i] / mid; //累计每根木棒可以切割的段数
}
if (count < K) //count小于要求的数量,为了增加count,需要减小L1,进入[left,mid]区间查找更小的L1
right = mid;
else //count大于等于要求的数量,为了减少count,就要加大L1,进入[mid+1,right]区间查找更大的L1
left = mid + 1;
}
printf("%d", left - 1); //最大长度L=L1-1
}