CCF-CSP第26次认证第一题——归一化处理
参考题解
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main () {
int n;
cin >> n;
int data [n] = {0};
int sum = 0;
for (int i = 0; i < n; i++) {
cin >> data[i];
sum += data[i];
}
double average = (double) sum / n;
double d = 0;
for (int i = 0; i < n; i++) {
double temp = data[i] - average; //注意:这一步不能用int类型,否则下面求平方可能会溢出导致丢失精度
d += temp * temp;
}
d /= n;
// 输出标准化结果,保证精度
cout << fixed << setprecision(10); // 设置输出精度
for (int i = 0; i < n; i++) {
cout << (data[i] - average) / sqrt(d) << "\n";
}
return 0;
}
优化后
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip> // 用于设置输出精度
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
// 读取数据
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
// 计算平均值
double mean = 0.0;
for (int i = 0; i < n; ++i) {
mean += a[i];
}
mean /= n;
// 计算方差
double variance = 0.0;
for (int i = 0; i < n; ++i) {
variance += (a[i] - mean) * (a[i] - mean);
}
variance /= n;
// 计算标准差
double stddev = sqrt(variance);
// 输出标准化结果,保证精度
cout << fixed << setprecision(10); // 设置输出精度
for (int i = 0; i < n; ++i) {
double normalized = (a[i] - mean) / stddev;
cout << normalized << endl;
}
return 0;
}
总结【有效数字相关】
此类题目注意定义的变量类型,int * int可能会溢出导致结果不准确,要用double
熟悉输出精度的设置:cout << fixed << setprecision(10); // 设置输出精度
#include <iostream>
#include <iomanip> // for setprecision, fixed
using namespace std;
int main() {
double pi = 3.141592653589793;
// 输出确到 5 位有效数字
cout << setprecision(5) << pi << endl; // 输出:3.1416
// 输出精确到 5 位有效数字(小数点后5位)
cout << fixed << setprecision(5) << pi << endl; // 输出:3.14159
// 输出精确到 10 位有效数字(小数点后10位)
cout << fixed << setprecision(10) << pi << endl; // 输出:3.1415926536
// 输出精确到 5 位有效数字(小数点后5位)---虽然这里没用fixed,但前面用的fixed最标准输出流产生了影响
cout << setprecision(5) << pi << endl; // 输出:3.14159
// 输出科学记数法表示
cout << scientific << setprecision(5) << pi << endl; // 输出:3.14159e+00
return 0;
}
#include <cstdio>
using namespace std;
int main() {
double pi = 3.141592653589793;
// 定点格式输出,保留小数点后 5 位
printf("%.5f\n", pi); // 输出:3.14159
// 定点格式输出,保留小数点后 10 位
printf("%.10f\n", pi); // 输出:3.1415926536
// 科学记数法输出,保留 5 位有效数字
printf("%.5e\n", pi); // 输出:3.14159e+00
// 自动选择定点或科学记数法,保留 5 位有效数字
printf("%.5g\n", pi); // 输出:3.1416
// 设置最小宽度为 10,小数点后 3 位
printf("%10.3f\n", pi); // 输出: 3.142 (总宽度 10,数字右对齐)
// 设置最小宽度为 10,科学记数法,小数点后 3 位
printf("%10.3e\n", pi); // 输出: 3.142e+00 (总宽度 10,数字右对齐)
// 输出宽度为 10,数字左对齐
printf("|%-10d|\n", num); // 输出:|42 |
return 0;
}