• 2018/7/31--zznu-oj-问题 G: 方差 普拉斯--【两重暴力循环求方差即可!】


    问题 G: 方差 普拉斯

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 94  解决: 17
    [提交] [状态] [讨论版] [命题人:admin]
    题目描述
    
    方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。在许多实际问题中,研究方差即偏离程度有着重要意义。
    若x1,x2,x3......xn的平均数为k,则方差s^2 = 1/n * [(x1-k)^2+(x2-k)^2+.......+(xn-k)^2] 。
    给出M个数,从中找出N个数,使这N个数方差最小。 
    输入
    
    第1行:2个数M,N,(M > N, M <= 10000)
    第2 - M + 1行:M个数的具体值(0 <= Xi <= 10000)
    输出
    
    输出最小方差 * N的整数部分。 
    样例输入
    
    5 3
    1
    2
    3
    4
    5
    样例输出
    
    2

    大致思路:

      1、求方差,暴力即可!暴力下来也只有两重for循环!不会超时!

      2、设下标从x1--x2的n个数的方差为s1,平均数k1,下标x1+1—x2+1 的方差为s2,平均数为k2, 前后两者有一点联系,就是平均数会涉及到一些重复计算,分别设为k1和k2,k2=k1-x1/n+(x2+1)/n,省去了一些计算复杂度!但是,方差s1和s2并不能直接像类似于k1和k2那样直接转化!那么s2需要老老实实地再计算一遍!(我看着样例,直接得出了s1得到s2的式子!WA了一次!)因此时间复杂度不会因为一点k1得到k2的优化而发生变化!毕竟乘法时间复杂更大!

      3、记得这个样本序列需要进行排序,升序排序一遍即可!不排序我WA了!

      4、别被题面吓住了!尤其是开篇的两道题目造成的深深的心理阴影,后面的题目其实才简单呢!!!多做题,才能克服自己内心深处的恐惧!

      5、会不会超double类型呢!貌似不会!假设(x1-k)等于1e4,那么平方会就是1e8,并且还有N个数,那个总的和就是1e12次方,基本会超过double了!不放心的话,可以在求xi的时候把(xi-k)*(xi-k)/N 调整成 (xi-k)/N*(xi-k),这样就肯定没问题了。

    题解:

      

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<string>
     5 #include<vector>
     6 #include<algorithm>
     7 #define ll long long
     8 using namespace std;
     9 #define N 10000
    10 #define ll long long
    11 double a[N+10];
    12 
    13 int main()
    14 {
    15     int m,n;
    16     while(scanf("%d%d",&m,&n)!=EOF){
    17         for(int i=1;i<=m;i++)
    18             scanf("%lf",&a[i]);
    19         sort(a+1,a+1+m);
    20      //   for(int i=1;i<=m;i++)
    21      //       printf("*%lf  ",a[i]);
    22 
    23         a[0]=0;
    24         double sum=0,k=0,s2=0,ans=999999999.9;
    25         for(int i=1;i<n;i++)
    26             sum+=a[i];
    27         for(int i=n;i<=m;i++){
    28             sum=sum+a[i]-a[i-n];
    29             k=sum/n;
    30             s2=0;
    31             for(int j=i;j>=i-n+1;j--)
    32                 s2=s2+(a[j]-k)/(1.0*n)*(a[j]-k);
    33             ans=min(ans,s2);
    34         }
    35 
    36         printf("%lld
    ",(ll)(ans*1.0*n+1e-8));
    37 
    38     }
    39 
    40 
    41     return 0;
    42 }
    View Code(两重for循环暴力就AC了!)

     

     

  • 相关阅读:
    sprinf sprintf_s 的用法
    c++中static的用法详解
    C++数值类型与string的相互转换
    setTimeout(function(){}, 0);
    学习 Node.js 的 6 个步骤
    $destroy——angular
    模态框——angular
    日期控件
    前端加密
    ui-router
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/9399700.html
Copyright © 2020-2023  润新知