木棒切割问题

点击查看代码
/*
木棒切割问题:
给定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
}

posted @ 2022-09-28 22:15  zhaoo_o  阅读(31)  评论(0编辑  收藏  举报