最近在看qsc的视频和代码,收益良多,就像之前我崇拜黄学长一样崇拜他,敬佩一个人也会学到很多东西的。
啊,这道二分,我终于搞定了,二分的模板也算大概掌握清楚了。
大概就分为两种来写
1. (int)http://www.cnblogs.com/qscqesze/p/5465788.html
2. (double)http://www.cnblogs.com/qscqesze/p/5296536.html
题目大意
有N个人,每个人有一定的存款,他们想通过转账让所有人最后的钱相等
转账时银行按比例收取手续费,问最后每个人最多能有多少钱
算法思路
二分答案,考察超过mid的钱在交付手续费后能否填补不够mid的钱
时间复杂度: O(NlogV)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
double k;int n;
bool check(double c)
{
double ret=0;
for(int i=0;i<n;i++)
{
if(a[i]<c)ret+=a[i]-c;
if(a[i]>c)ret+=(a[i]-c)*(1-k);
}
if(ret>=0)return 1;
else return 0;
}
int main()
{
int T;
cin>>T;
while(T--){
scanf("%d%lf",&n,&k);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
double l=0,r=0;
for(int i=0;i<n;i++)
r+=a[i];
r/=n;
double ans=0;
while(r-l>1e-10)
{
double mid=(l+r)/2;
if(check(mid))l=mid,ans=mid;
else r=mid;
}
printf("%.6f\n",ans);
}
}