https://ac.nowcoder.com/acm/contest/80259/F
我们先从1--n每一个元素看,对于a[i],可以后悔,这样相当于在n个元素中挑2个的期望,
为2*sum/n,假如没有后悔,剩下的期望就是(sum-a[i])/(n-1)了,此时我们还有一次反悔机会
我们不妨先排个序,假如我们选到了比期望大的数那么我们就直接选(否则下一次就是期望了),反之我们就返回使其值变成期望,于是答案就是(su[i]+(id-1)*k)(su[i]用后缀和维护),其中包含了原本去的a[i],我们把它减去即可。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
double su[100010];
bool cmp(double a,double b)
{
return a<b;
}
double a[100010];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(n==1) cout<<a[1];
if(n==1) return 0;
sort(a+1,a+n+1,cmp);
for(int i=n;i>=1;i--) su[i]=su[i+1]+a[i];
//第一次就后悔
double s=2*su[1]/n;
//遍历1--n,每次取出一个取max
double ans=0;
for(int i=1;i<=n;i++)
{
double k=(su[1]-a[i])/(n-1);
int id=lower_bound(a+1,a+n+1,k)-a;
double tmp=su[id]+(id-1)*k;
if(a[i]>=k) tmp-=a[i];
else tmp-=k;
tmp/=n-1;
ans+=max(tmp+a[i],s);
}
printf("%.11lf",ans/n);
}