POJ No .1064题解

POJ No .1064题解

题目Cable master

###题目描述
有 N 条绳子,它们的长度分别为 Li。如果从它们中切割出 K条长度相同的绳子,这 K 条绳子每条最长能有多长?答案保留到小数点后 2 位(直接舍掉 2位后的小数)。

###输入格式
第一行两个整数 N 和 K,接下来 N 行,描述了每条绳子的长度 Li

###输出样例
输入:4 11 输出: 2.00
8.02
7.43
4.57
5.39

###说明/提示
对于 100%100% 的数据 0<Li <=100000.00, 0<n<10000,0<n≤10000,0<k≤10000

该题在洛谷也有整形的
整形二分题目链接
整形题解

题目用二分搜索可以容易求得答案
条件:
C(x) = 可以得到K条长度为x的绳子
则该问题转变为求满足条件的最大的x。在区间初始化时,只需用最大的数INF(>MAXl)作为右边界即可:
l= 0
r = INF
现在的问题是是否可以高效的判断C(x),则由于长度为L1的绳子最多切出(L1/x)段长度为x的绳子,因此:
####C(x) = (L1/x) 的总和是否大于等于K。
该种方式的时间复杂度应该是O(N)我是菜鸡如果想的不对希望大佬指正
该题的核心代码应该是 如何判断是否继续二分,既假定一个解并判断是否可行`sum2 = 0;

返回值为bool类型

for (int i = 0;i < n;i++)
{
	sum2 = sum2 + b[i] / t;
}
return sum2 < k;`

sum2 在该函数前要初始化,每次调用该函数要保证sum2的值为0.

下面贴AC代码

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<queue>
#include<stack>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
#define N 10000
double a[N];
long long b[N];
long long n, k, l;
long long sum, r, sum2, ans, mid;
bool j(int t)
{
	sum2 = 0;
	for (int i = 0;i < n;i++)
	{
		sum2 = sum2 + b[i] / t;
	}
	return sum2 < k;
}
int main()
{
	cin >> n >> k;;
	for (int i = 0;i < n;i++) {
		int temp;
		cin >> a[i];
		b[i] = a[i] * 100;//因为小数精度不好搞所以乘100转换为整数
		sum = sum + b[i];
	}
	r = sum / k + 1;
	while (l < r)
	{
		mid = (l + r + 1) / 2;//期中二分时(l+r)必须加一不然会爆
		if (mid == 0)
			break;
		if (j(mid))
		{
			r = mid - 1;//这右界也要减一
		}
		else
		{
			l = mid;

		}
	}
	printf("%.2lf", l * 1.00 / 100);//最后在除100转化回来
	//并保留两位小数
}

**谢谢大家,*有错的希望大佬指正 ***

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值