题目大意:
输入n, w, m 代表有n个桶,每桶w升牛奶,m个杯子等待分配牛奶,要求没个杯子中的牛奶量相同,且每个桶至多给2个杯子分配牛奶,若可以分配,输出YES,和个杯子是由第几个桶 分配了多少升,若不能分配输出NO。
思路:
用贪心的思想将每个桶中的牛奶每次最大量的分出,用vector<结构体>记录下分配过程,此外由于可能出现除不尽的情况,因此还要控制下精度,使用fabs(a-b)与1e-6比较即可。
ac代码:
#include <iostream>
#include <vector>
#include <cmath>
#define pause system("pause")
#define cout(x) cout << fixed << setprecision(x)
using namespace std;
const int maxn = 305;
int n ,w, m;
typedef struct node
{
double w;
int n;
node(double ww, int nn) {
w = ww;
n = nn;
}
} node;
double wi[maxn];
int use[maxn];
double mi[maxn];
vector<node>Get[maxn];
double avg;
void init()
{
for (int i = 1; i <= max(m, n); i++) {
use[i] = 0;
wi[i] = (double) w;
mi[i] = 0;
Get[i].clear();
}
}
bool Fill(int inx)
{
//cout << "inx = " << inx << endl;
for (int i = 1; i <= n; i++) {
if (wi[i] == 0) continue;
if (fabs(wi[i] + mi[inx] - avg) <= 1e-6) {
//cout << 1 << endl;
Get[inx].push_back(node(wi[i], i));
wi[i] = 0;
mi[inx] = avg;
}
else if (wi[i] > avg - mi[inx]) {
//cout << 2 << endl;
wi[i] -= (avg - mi[inx]);
Get[inx].push_back(node(avg - mi[inx], i));
mi[inx] = avg;
}
else
{
//cout << 3 << endl;
Get[inx].push_back(node(wi[i], i));
mi[inx] += wi[i];
wi[i] = 0;
}
use[i]++;
if (use[i] > 2) return false;
if (fabs(avg - mi[inx]) <= 1e-6) return true;
}
return true;
}
int main()
{
cin >> n >> w >> m;
if (m > 2 * n) cout << "NO" << endl;
else
{
if (n == m) {
cout << "YES" << endl;
for (int i = 1; i <= n; i++) cout << i << " " << w << endl;
}
else {
avg = (double) (n * w) / m;
init();
int flag = 1;
//if (n < m) {
for (int i = 1; i <= m; i++) {
bool f = Fill(i);
if (!f) {
flag = 0;
break;
}
}
if (!flag) cout << "NO" << endl;
else
{
cout << "YES" << endl;
for (int u = 1; u <= m; u++) {
for (int i = 0; i < Get[u].size(); i++) {
if (i) cout << " ";
printf("%d %.6lf", Get[u][i].n, Get[u][i].w);
}
cout << endl;
}
}
//}
}
}
return 0;
}