Robert 的军队

来源:互联网 发布:不上班的23种活法 知乎 编辑:程序博客网 时间:2024/05/16 15:27

题目

这里写图片描述
(ps:同学出的题诶………)
样例输入:
这里写图片描述
5 3 4
3 2 4 1 4
样例输出:
这里写图片描述
0.222

数据范围:
这里写图片描述


思路:这种题靠思维,注意方差的定义中,蕴含的一些特殊条件。


解法:
暴力,期望得分10~30分。
其中可以推出求方差S的公式:
平均数x=ni=1a[i]/n
方差S=ni=1(a[i]x)2,将这个东西拆开:
S=(ni=1a[i]2-2xni=1a[i]+nx)/n
=(ni=1a[i]2)/n-x;
所以只需要计算出a[i]与a[i]2的和便可以了,用前缀和记录一下。
优化一:可以具方差的定义知道,选的数里每对数的差越小,则方差越小。所以我们直接从小到大排个序,再取连续的一段。这样时间复杂度O(n(RL+1)),期望得分50~60分。
优化二:其实可以证出,方差不可能随着选的数的增加而减小,所以我们只需要考虑长度为L的方差便可以了。时间复杂度O(n)。对应100分。


代码:

#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define ll long longusing namespace std;const int maxn=100005;double s[maxn],s2[maxn],ans;ll h[maxn],n,l,r;int main(){    freopen("army.in","r",stdin);    freopen("army.out","w",stdout);    scanf("%d%d%d",&n,&l,&r);    fo(i,1,n) scanf("%lld",&h[i]);    sort(h+1,h+n+1);    fo(i,1,n){        s[i]=s[i-1]+h[i];        double x=h[i]*h[i];        s2[i]=s2[i-1]+x;    }    ans=10000000000;    fo(i,l,n){        double x=(s[i]-s[i-l])/l;        double k1=(s2[i]-s2[i-l])/l;        double k=k1-x*x;        if (k<ans) ans=k;    }    printf("%.3lf",ans);    fclose(stdin); fclose(stdout);}

这里写图片描述

0 0
原创粉丝点击