每日一题#559. 剪绳子(3月27日)

题目描述

有 N 根绳子,第 i 根绳子长度为 Li ,现在需要 M 根等长的绳子,你可以对 N 根绳子进行任意裁剪(不能拼接),请你帮忙计算出这 M 根绳子最长的长度是多少。

输入格式

第一行包含 2 个正整数 N, M,表示原始绳子的数量和需求绳子的数量。
第二行包含 N个整数,其中第 i 个整数 Li
​表示第 i 根绳子的长度。

输出格式

输出一个数字,表示裁剪后最长的长度,保留两位小数。

样例

输入数据 1
3 4
3 5 4
输出数据 1
2.50
数据范围

1≤N,M≤100000

0<Li<109

代码

一开始没思路,我想着直接模拟,代码如下:

//模拟版(超时) 
//剪绳子(3月27日)
#include<iostream>
#include<algorithm>
using namespace std;

int n , m;
int a[100010];
int maxx = -1;

int main(){
	
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i++){
		cin >> a[i];
		maxx = max(a[i] , maxx);
	}
	sort(a+1 , a+n+1);
	double i;
	long long int max_num = 999999999;
	double ans = -1;
	for(i = 0.005 ; i <= maxx ; i += 0.005){
		long long int num = 0;
		for(int j = 1 ; j <= n ; j++){
			num = num + a[j]/i;
			if(num >= m) break;
		}
//		cout << num << " " << i << endl;
		if(num >= m){
			if(i >= ans){
				ans = i;
//				cout << "max_num = " << max_num << ",ans = " << ans << endl;
			}
		}
		else{
			break;
		}
	}
	
	printf("%.2f" , ans);
	
	return 0;
} 

结果不出所料的严重超时了,所以就用了题解所说的二分查找
代码如下:

//剪绳子(3月27日)
#include<iostream>
#include<algorithm>
using namespace std;

int n , m;
int sum;
int a[100010];
int max_len = -1;

double binary_search(int len){
	double left = 0;
	double right = len;
	double mid;
	while(left < right){
		mid = (left+right) / 2;
		sum = 0;
		for(int i = 1 ; i <= n ; i++){
			sum += a[i]/mid;
		}
		if(sum < m){
			right = mid - 0.0005;
		}
		else if(sum >= m){
			left = mid + 0.0005;
		}
	}
	return left;
}

int main()
{
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i++){
		cin >> a[i];
		max_len = max(max_len , a[i]);
	}
	
	double ans = binary_search(max_len);
	printf("%.2f" , ans);

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值