uva-410
题意:国际空间站在其实验室中包含许多离心机。每个离心机将具有一些(C)个腔室,每个腔室可包含0,1或2个样品。您将编写一个程序,将所有S样本分配给腔室,使得没有腔室包含超过2个样本,并且IMBALANCE的以下表达式被最小化。 (来自谷歌翻译)
每行数的和与c/s的差的绝对值就是imbalance.
题解:
若s为零,则imbalance为零,但输出格式仍然需要体现。若s<=c,说明可能某一行的可以不放置,故只需要一个放一行即可,(若一行放两个,imbalance将变大)。
若s>c,又有一些行必须放一个数字的话,放单个数字的地方必须是元素里面最大的那几个,否则将造成的大的数越大,小的数越小,imbalance的值也会越大。
思路是贪心,先排序,如果S<C 那么直接填,否则的话,先处理大的,将前2*C-S个大数占一个格子,剩下的几个,按两头取,例如:1 2 3 4 取 1,4和2,3分别填到格子里!
s==0时也要输出的格式
if (s == 0)
{
for (int i = 0; i < c; ++i)
{
ans += ave;
cout << ' ' << i << ":" << endl;
}
}
s<=c时,每一腔室放一个,也有的空着;用a数组进行标记
如果s放完了那就只输出i;
else if (s <= c)
{
int k = 0;
for (int i = 0; i < c; ++i)
{
ans += fabs(a[k] - ave);
cout << ' ' << i << ":";
if (a[k] != 0)
cout << ' ' << a[k++];
cout << endl;
}
}
s>c的情况,最开始对a数组进行排序,先处理大的,将前2*C-S个大数占一个格子,剩下的几个,按两头取,例如:1 2 3 4 取 1,4和2,3分别填到格子里!
else
{
int p = 2 * c - s, k = 0;
for (int i = 0; i < c; ++i)
{
cout << ' ' << i << ':';
if (p)
{
cout << ' ' << a[s - i - 1] << endl;
ans += fabs(a[s - i - 1] - ave);
p--;
}
else
{
ans += fabs(a[m - i - 1] + a[k] - ave);
cout << ' ' << a[m - i - 1] << ' ' << a[k++] << endl;
}
}
}
完整代码:
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
int n, m;
int main()
{
int ca = 1;
while (cin >> n >> m)
{
int a[15];
memset(a, 0, sizeof(a));
double ave = 0, ans = 0;
for (int i = 0; i < m; ++i)
{
cin >> a[i];
ave += a[i];
}
ave /= n;
sort(a, a + m);
cout << "Set #" << ca++ << endl;
if (m == 0)
{
for (int i = 0; i < n; ++i)
{
ans += ave;
cout << ' ' << i << ":" << endl;
}
}
else if (m <= n)
{
int k = 0;
for (int i = 0; i < n; ++i)
{
ans += fabs(a[k] - ave);
cout << ' ' << i << ":";
if (a[k] != 0)
cout << ' ' << a[k++];
cout << endl;
}
}
else
{
int p = 2 * n - m, k = 0;
for (int i = 0; i < n; ++i)
{
cout << ' ' << i << ':';
if (p)
{
cout << ' ' << a[m - i - 1] << endl;
ans += fabs(a[m - i - 1] - ave);
p--;
}
else
{
ans += fabs(a[m - i - 1] + a[k] - ave);
cout << ' ' << a[m - i - 1] << ' ' << a[k++] << endl;
}
}
}
printf("IMBALANCE = %.5lf\n\n", ans);
}
}