分为两种情况:
- 小室数量 >= 样本数量,每个小室内放一个样本;
- 小室数量 < 样本数量,首先按样本重量从大到小排序,将重量最大的 2*C-S 个样本单独放置,剩余的样本一个最重的和一个最轻的组合放置。比如样本重量为 5,4,3,2,1,小室数量为 3,则 5 单独放置,4 和 1 组合放置,3 和 2 组合放置。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
int cell[5]; //小室
double sum; //样本总质量
int C, S; //小室数,样本数
struct Specimen //样本
{
int mass; //质量
int order; //在输入中的顺序
int group; //所属组号
bool vis; //访问情况
}s[10];
//按照质量从大到小排序
bool cmp1(Specimen s1, Specimen s2)
{
return s1.mass > s2.mass;
}
//按照输入顺序从小到大排序
bool cmp2(Specimen s1, Specimen s2)
{
return s1.order < s2.order;
}
//计算IMBALANCE值
double Imbalance()
{
double avg = sum / C;
double ans = 0;
for (int i = 0; i < C; i++)
{
ans += fabs(cell[i] - avg);
}
return ans;
}
int main()
{
int Case = 0;
while (cin >> C >> S)
{
memset(cell, 0, sizeof(cell));
sum = 0;
if (C >= S) //小室数量 >= 样本数量
{
for (int i = 0; i < S; i++)
{
cin >> s[i].mass;
sum += s[i].mass;
cell[i] = s[i].mass;
}
cout << "Set #" << ++Case << endl;
for (int i = 0; i < S; i++)
{
cout << " " << i << ": " << s[i].mass << endl;
}
cout << "IMBALANCE = " << fixed << setprecision(5) << Imbalance() << endl << endl;
}
else //小室数量 < 样本数量
{
int single = 2 * C - S; //只有一个数的格子的数量
for (int i = 0; i < S; i++)
{
cin >> s[i].mass;
sum += s[i].mass;
s[i].order = i;
s[i].vis = 0;
}
sort(s, s + S, cmp1); //按照样本重量从大到小排序
for (int i = 0; i < single; i++) //单独放置single个最重的样本
{
cell[i] = s[i].mass;
s[i].group = i;
}
for (int i = single; i < single + (S - single) / 2; i++) //两两组合放置剩余样本
{
cell[i] = s[i].mass + s[single + S - 1 - i].mass;
s[i].group = s[single + S - 1 - i].group = i;
}
cout << "Set #" << ++Case << endl;
sort(s, s + S, cmp2); //还原为输入顺序
for (int i = 0; i < C; i++)
{
cout << " " << i << ": ";
int j;
for (j = 0; j < S; j++)
{
if (!s[j].vis)
{
cout << s[j].mass;
s[j].vis = true;
break;
}
}
for (int k = j + 1; k < S; k++)
{
if (s[k].group == s[j].group)
{
cout << " " << s[k].mass;
s[k].vis = true;
break;
}
}
cout << endl;
}
cout << "IMBALANCE = " << fixed << setprecision(5) << Imbalance() << endl << endl;
}
}
return 0;
}
继续加油。