该程序适用于数据分组,即分出组内离差平方和最小的2组
感谢同学开源。
背景
在《义务教育教科书 数学 八年级下册》(浙江教育出版社)的第78页出现了特别猎奇的题目:


To solve the problem,神人同学使用了十分牛逼,牛逼上天的C++编写了一个符合教科书中要求的程序。
程序设计
/*
用于计算如下问题:
给定一组数据x1,x2,...,xn
把这组数据分成两组,使组内离差平方和最小。
先输入n,再输入n个数,就可找出最优分组方案和对应的组内离差平方和
*/
#include<bits/stdc++.h>
using namespace std;
#define N 109
int n;
double a[N],sum[N];
int main()
{
scanf("%d",&n);
sum[0] = 0;
for(int i=1;i<=n;i++)
{
scanf("%lf",&a[i]);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
sum[i] = sum[i-1] + a[i];
double x=1.0*sum[n]/n;
double d=0;
for(int i=1;i<=n;i++)
{
d += 1.0*(a[i]-x)*(a[i]-x);
}
printf("x=%.2lf D^2=%.2lf\n",x,d);
// 把前i个分成一组,剩余的分成另一组
double mn=1145141919810,ans;
for(int i=1;i<=n-1;i++)
{
double x1=1.0*sum[i]/i,x2=1.0*(sum[n]-sum[i])/(n-i);
double d12=d-1.0*i*(x1-x)*(x1-x)-1.0*(n-i)*(x2-x)*(x2-x);
if(d12<mn)
{
mn=d12;
ans = i;
}
for(int j=1;j<=i;j++)
{
if(j<i) printf("%.2lf ",a[j]);
else printf("%.2lf",a[j]);
}
printf("|");
for(int j=i+1;j<=n;j++)
{
printf("%.2lf ",a[j]);
}
printf(" %.2lf\n",d12);
}
printf("\n最优分组方案:\n");
for(int i=1;i<=ans;i++)
{
if(i<ans) printf("%.2lf ",a[i]);
else printf("%.2lf",a[i]);
}
printf("|");
for(int i=ans+1;i<=n;i++)
{
printf("%.2lf ",a[i]);
}
printf(" %.2lf\n",mn);
return 0;
}
效果展示

本文采用 CC BY-NC-SA 4.0 国际许可协议进行许可。
转载请注明作者及原文链接,并遵循相同方式共享原则。
链接:




