B3798 题解

· · 题解

本题是一个纯模拟。

我们先根据公式算出每一个人的标准差,然后进行排序即可。

在算标准差时,我们知道,本题只需要一个大小排名,并不需要每个人准确的标准差。因此,我们不必算 \sqrt{\dfrac{\sum(X-\mu)^2}{N}},只需要算出 {{\sum(X-\mu)^2}} 即可,也不需要考虑精度问题。

注意几个问题:

  1. 最后最多也只需要输出 20 个人,需要判断。

  2. 排序有两个关键字,先按标准差,再按姓名的字典序。

  3. 算标准差时需要使用 double 类型的变量。

接下来,代码就好写了:

#include <bits/stdc++.h>
using namespace std;
int n,m;
struct info
{
    string name;//姓名
    double sum;//标准差
}a[100001];
bool cmp(info x,info y)
{
    return x.sum>y.sum//第一个关键字,标准差降序排序
   ||(x.sum==y.sum&&x.name<y.name);//第二个关键字,当标准差相同时,字典序升序排序
}
int main()
{
    ios::sync_with_stdio(0);//本题建议使用IO优化
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int b[25]={0},sum=0;//用b数组记录第i个人的每科成绩,sum为分数和
        cin>>a[i].name;
        for(int j=1;j<=m;j++)
            cin>>b[j],sum+=b[j];
        double pjz=(sum*1.0)/(m*1.0);//求平均值,要考虑int转double的问题
        for(int j=1;j<=m;j++)
            a[i].sum+=(pjz-b[j])*(pjz-b[j]);//可以简化成我这样
     } 
     sort(a+1,a+1+n,cmp);//排序
     for(int i=1;i<=min(20,n);i++) cout<<a[i].name<<endl;//输出前20人
    return 0;
}