1. 程式人生 > >CodeForces - 93B 貪心+精度控制

CodeForces - 93B 貪心+精度控制

題目大意:

輸入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;
}