查找专题-Cable master

原题链接原题链接
题目描述:首先输入电缆的个数n,和要分的等长份数k,然后分别输入n个电缆的长度length[i],最后要求输出分后电缆的最长长度。
题目思路:这个题要求求最大长度,可以说是一个最值问题,可以用二分法来求。可以求得所有的电缆的总长度sum,所以大致的二分的范围即sum/k,因为如果分后电缆长度大于sum/k,那么k份电缆的总长度就会大于sum。可以在这个范围内对电缆长度进行二分得mid,然后判断按mid所分的份数number是否满足条件,即若所有的(int)(length[i]/mid)求和所的number大于等于k,那么说明电缆长度还可以再大,所以令left=mid;如果小于k,则说明此长度比最大值要大,所以令right=mid;当left与right的误差缩小一定值的时候,就可以输出结果left了。
注意事项:这个题比较坑人的地方就是要求保留两位小数,但c保留时会自动四舍五入,为了避免这个问题可以有两个解决方法:1.用length[i]-0.005,这样如果length[i]=6.666,减去后即为6.661,这样保留结果为6.66,同样若length[i]=6.661,减去后即为6.656,保留后的结果仍然为6.66。2.可以用函数floor,函数的意义是向下取整,先将结果乘以100然后向下取整,再除以100这样就可以避免四舍五入的问题了。
代码部分

#include<stdio.h>
#include <stdlib.h>
#include <math.h>
#define st 1e-8
double length[10010];
int n;
int m;
int num(double a)
{
	int i, number = 0;
	for (i = 0; i < n; i++)
		number += (int)(length[i] / a);
	return number;
}
int main()
{
	int i;
	scanf("%d%d", &n, &m);
	double sum = 0;
	int number = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%lf", &length[i]);
		length[i] = length[i];
		sum = sum + length[i];
	}
	sum = sum / m;
	double right = sum, left = 0, mid;
	while (fabs(right - left) > st)
	{
		mid = (right + left) / 2;
		if (num(mid) >= m)
			left = mid;
		else
			right = mid;
	}
	printf("%.2f\n", float(floor(left * 100)) / 100);
	return 0;
}

写的有点急,如果有错误,欢迎在下方留言。

努力努力再努力x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值