统计监控数据
题意
输入一行浮点数,总个数是 19 的整数倍。把它们按每 19 个一组拆成若干样本,然后对 19 列特征分别计算 8 个统计量:mean、max、min、ptp(极差)、std(总体标准差)、var(总体方差)、skew(总体偏度)、kurt(总体超峰度)。
所有结果保留两位小数,按特征 0 到特征 18 的顺序输出,每个特征输出 8 个值,用空格分隔。
思路
这题本身不涉及算法设计,纯粹是统计公式的实现。唯一需要注意的是偏度和峰度的定义用的是总体公式,分母是 而不是
。
数据整理: 读入所有浮点数后,按 19 个一组划分成 个样本。然后对第
列,取出所有样本在该列的值组成数组
。
基础统计量: mean、max、min 没什么好说的。ptp 就是 max min。总体方差
,标准差
。
偏度和峰度怎么算? 先把每个值标准化:,然后:
$$
$$
减 3 是因为正态分布的四阶矩为 3,减去之后得到的是"超峰度"。当 时(所有值相同),偏度和峰度都定义为 0。
一个小细节: 样例里 3 个等差数据的 kurt 是 。用公式验证一下:
取
(标准化后的值),
之和为 2,平均为
,减 3 得
……等等,这和
对不上?
别急,标准差是 ,原始数据比如
,mean
,
。
,两个加起来
,平均
,减 3 就是
。没错,关键是
不是
,因为标准差不是 1。
复杂度
- 时间:
,对每列遍历所有样本
- 空间:
,存储所有数据
代码
import sys
def solve():
data = list(map(float, sys.stdin.read().split()))
n = len(data) // 19
samples = []
for i in range(n):
samples.append(data[i * 19:(i + 1) * 19])
results = []
for col in range(19):
vals = [samples[row][col] for row in range(n)]
mean = sum(vals) / n
mx = max(vals)
mn = min(vals)
ptp = mx - mn
var = sum((x - mean) ** 2 for x in vals) / n
std = var ** 0.5
if std == 0:
skew = 0.0
kurt = 0.0
else:
skew = sum(((x - mean) / std) ** 3 for x in vals) / n
kurt = sum(((x - mean) / std) ** 4 for x in vals) / n - 3
results.extend([mean, mx, mn, ptp, std, var, skew, kurt])
print(' '.join(f'{x:.2f}' for x in results))
solve()
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<double> data;
double x;
while(cin >> x) data.push_back(x);
int n = data.size() / 19;
cout << fixed << setprecision(2);
for(int col = 0; col < 19; col++){
vector<double> vals(n);
for(int i = 0; i < n; i++) vals[i] = data[i * 19 + col];
double mean = 0, mx = vals[0], mn = vals[0];
for(auto v : vals){ mean += v; mx = max(mx, v); mn = min(mn, v); }
mean /= n;
double ptp = mx - mn;
double var = 0;
for(auto v : vals) var += (v - mean) * (v - mean);
var /= n;
double std_ = sqrt(var);
double skew = 0, kurt = 0;
if(std_ != 0){
for(auto v : vals){
double z = (v - mean) / std_;
skew += z * z * z;
kurt += z * z * z * z;
}
skew /= n;
kurt = kurt / n - 3;
}
double res[] = {mean, mx, mn, ptp, std_, var, skew, kurt};
for(int i = 0; i < 8; i++){
if(col > 0 || i > 0) cout << ' ';
cout << res[i];
}
}
cout << endl;
}

京公网安备 11010502036488号