UVA410(贪心)

The International Space Station contains many centrifuges in its labs. Each centrifuge will have some
number © of chambers each of which can contain 0, 1, or 2 specimens. You are to write a program
which assigns all S specimens to the chambers such that no chamber contains more than 2 specimens
and the following expression for IMBALANCE is minimized.
IMBALANCE =

C
i=1
| CMi − AM |
where:
CMi
is the Chamber Mass of chamber i and is computed by summing the masses of the specimens
assigned to chamber i.
AM is the Average Mass of the chambers and is computed by dividing the sum of the masses of all
specimens by the number of chambers ©.
Input
Input to this program will be a file with multiple sets of input. The first line of each set will contain
two numbers. The first number (1 ≤ C ≤ 5) defines the number of chambers in the centrifuge and the
second number (1 ≤ S ≤ 2C) defines the number of specimens in the input set. The second line of
input will contain S integers representing the masses of the specimens in the set. Each specimen mass
will be between 1 and 1000 and will be delimited by the beginning or end of the line and/or one or
more blanks.
Output
For each input set, you are to print a line specifying the set number (starting with 1) in the format
‘Set #X’ where X is the set number.
The next C lines will contain the chamber number in column 1, a colon in column number 2, and
then the masses of the specimens your program has assigned to that chamber starting in column 4.
The masses in your output should be separated by exactly one blank.
Your program should then print ‘IMBALANCE = X’ on a line by itself where X is the computed
imbalance of your specimen assignments printed to 5 digits of precision to the right of the decimal.
The final line of output for each set should be a blank line. (Follow the sample output format.)

Sample Input
2 3
6 3 8
3 5
51 19 27 14 33
5 9
1 2 3 5 7 11 13 17 19
Sample Output
Set #1
0: 6 3
1: 8
IMBALANCE = 1.00000
Set #2
0: 51
1: 19 27
2: 14 33
IMBALANCE = 6.00000
Set #3
0: 1 17
1: 2 13
2: 3 11
3: 5 7
4: 19
IMBALANCE = 11.60000

题意:输入n,m再输入m个数,然后把m个数相加的和除以n,成为一个平均数。然后要你把这个m个数分给n个室,没个室最多分两个数,问你怎么分才能使每个室的数之和减掉平均值的绝对值之和最小。
题解:把 m个数从小到大排好,若是m<=n,那很容易,一个室分一个,分完即止,因为你如果两个数分到一起,那你就会多空出一个室,即多了个平均数(如数a和数b,如果你把a,b分别分到一个室的话,平均数为v,那结果是fabs(a-v)+fabs(b-v),而你分到一起的话,结果是v+fabs(a+b-v),这两个数谁大呢?;利用一下绝对值不等式即可fabs(v)+fabs(a+b-v)>=fabs(v+a+b-v)=fabs(a+b)>=fabs(a-b)>=fabs(a-v)+fabs(b-v))所以不可以。
若m>n呢,从大到小排好,前几大的数肯定要各在一室,如果你大的和大的在一起,只会离平均数更远,那么要所有数更可能的离平均值更近一点,就只能最大的和最小的了,但要注意m不一定等于2n,所以不是所有的室都有两个,则需要从小的室分配剩下最大的,分完即可。
特别要注意的是里面的格式,太坑了,wa了好多次

ac代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <cstdlib>
#include <queue>
#include<iomanip>
using namespace std;
bool cmp(int a, int b)
{
	return a > b;
}
int main()
{
	int a[10];
	int n, m;
	int k = 1;
	double kkk;
	while (cin >> n >> m)
	{
		double ant = 0, sum = 0;
		memset(a, 0, sizeof(a));
		for (int i = 0; i < m; i++)
		{		cin >> a[i];
		ant += a[i] * 1.0;
		
		}ant /= n; 
		sort(a, a + m,cmp);
		cout << "Set #" << k << endl;
		if (m <= n)
		{
			for (int i = 0; i < n; i++)
			{
				cout << ' '<<i << ":";
				if (i < m)cout << ' '<<a[i];//注意空格要这里输出,一个室如果没有数,不能输出空格要直接换行,一直掉这里了
				 cout << endl;
				sum += fabs(a[i] - ant);
			}
		}
		else
		{
			for (int i = 0; i < n; i++)
			{
				cout <<' '<< i << ": ";//前面的空格也容易忽视,别忘了
				cout << a[i]; 

				if (a[2*n-i-1]> 0) { cout << ' ' << a[2 * n - i - 1] << endl;	kkk = a[2 * n - i - 1] * 1.0; }//因为原先已经初始化为0了
				else {
					cout << endl; kkk = 0;
				}

				sum += fabs(a[i] + kkk - ant);
			}
		}
		cout << "IMBALANCE = ";
		printf("%.5f\n\n", sum);
		k++;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43965698/article/details/87900528