题目链接:https://www.nowcoder.com/acm/contest/143/A
题目大意:给定 n 门课以及它们的学分和绩点,定义总绩点是所有课的加权平均数,给定一个数 k,你可以删除最多 k 门课,求你的总绩点最大能到多少
1 <=n <=10^5
题目思路:
二分答案,假设当前二分了一个值D,我们要判断是否存在一个方案使得总绩点>=D
于是选前 k 个最小的s[i](c[i]-D)删除之后,判断值是否大于0即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
const double eps=0.00000001;
int n,k;
double s[maxn],c[maxn];
double a[maxn];
bool check(double d)
{
double sum=0;
for(int i=0;i<n;i++)
{
a[i]=1.0*s[i]*(c[i]-d);
sum+=a[i];
}
sort(a,a+n);
double num=0;
for(int i=0;i<k;i++)
{
num+=a[i];
}
if(sum-num>=0)return true;
else return false;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
double l=0x3f3f3f3f,r=0;
for(int i=0;i<n;i++)scanf("%lf",&s[i]);
for(int i=0;i<n;i++)
{
scanf("%lf",&c[i]);
r=max(r,c[i]);
l=min(l,c[i]);
}
double ans;
while(fabs(r-l)>eps)
{
double mid=(l+r)/2;
if(check(mid))
{
l=mid;
ans=mid;
}
else
{
r=mid;
}
}
printf("%f\n",ans);
}
return 0;
}