牛客-wyh的物品——通过验证得出二分的搜索区间

Posted C+++++++++++++++++++

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客-wyh的物品——通过验证得出二分的搜索区间相关的知识,希望对你有一定的参考价值。

题目

题目链接

题目详解

以下为手写详解

下面总结这个做题步骤:

  1. 二分搜索可能的最大单位价值。
  2. 根据这个值得到每个数的单位价值情况s,根据s的值排序,得到前k大的s,相加得出我们枚举的这个最大单位价值是大了还是小了,方便后续二分!

最后按保留两位小数,输出即可。

解题代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5; 
int w[maxn],v[maxn];
double s[maxn]; //TODO 存下用于比对实际单位价值的信息
int n,k;
using namespace std;

int solve(double mid)

	double ss = 0;
	for(int i = 0;i<n;i++)
	
		s[i] = 1.0*v[i] - w[i]*mid;
	
	sort(s,s+n,greater<double>());//TODO 从大到小排序,因为要取前k个最大值
	for(int i = 0;i<k;i++)
		ss += s[i];
    //TODO 得到前k个最大的s信息的和,
    // 如果大于0,则说明取小了,小于0则取大了,等于0则正好满足!
	if(ss>0) return 1;
    else if(ss==0)return -1;
	else return 0;

int main()

	int t;
	cin>>t;
	while(t--)
	
		scanf("%d %d",&n,&k);
		double low = 0,high = 100000,mid;
		for(int i = 0;i<n;i++)
		
			scanf("%d %d",&w[i],&v[i]);
		
        //TODO 二分搜索,由于double类型的二分,故取一个小数形式进行比对
        // 注意double类型的二分,千万别+1或者-1!这个跨度太大了,因为我们搜的是个分数!
		while(high - low >0.00001)
		
			mid = (low + high)/2.0;
            int flag = solve(mid);
			if(flag==1) low = mid;//TODO 收缩左边界
            else if(flag == -1)break;//TODO 枚举得到答案
			else high = mid;//TODO 收缩右边界
 
		
		printf("%.2lf\\n",mid);
	
	return 0;

以上是关于牛客-wyh的物品——通过验证得出二分的搜索区间的主要内容,如果未能解决你的问题,请参考以下文章

2021牛客暑期多校训练营4Average (二分答案,区间/子数组最大平均值,)

二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组

P1314 聪明的质监员

hdu5285-wyh2000 and pupil-(染色法二分图判定)

关于二分搜索 简单左侧区间右侧区间

牛客白月赛17题解