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+00return 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;
}