Cod sursa(job #1792130)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 30 octombrie 2016 01:17:32
Problema Sate2 Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 1.82 kb
#include <iostream>
#include <fstream>
#include <random>
#include <vector>
#include <cassert>
#include <algorithm>

using namespace std;

struct Sat{
    vector<int> catune;
    int totalSum;

    void add(int e){
        catune.push_back(e);
        totalSum += e;
    }

    int remove(size_t pos){
        assert(0 <= pos && pos < catune.size());
        swap(catune[pos], catune[catune.size() - 1]);

        int e = catune.back();
        catune.pop_back();
        totalSum -= e;

        return e;
    }

    size_t size(){
        return catune.size();
    }

    bool operator < (const Sat &sat) const{
        return totalSum < sat.totalSum;
    }
};

int main()
{
    ifstream in("sate2.in");
    ofstream out("sate2.out");

    int T;
    in >> T;

    while (T--){
        int N, M, K;
        in >> N >> M >> K;

        random_device rd;
        mt19937 gen(rd());
        uniform_int_distribution<> distrib(0, K - 1);

        vector<Sat> sate(K);

        for (int i = 0; i < N; ++i){
            int x;
            in >> x;
            sate[distrib(gen)].add(x);
        }

        if (M % K){
            cout << "NU\n";
            continue;
        }

        const int target = M / K;

        const int ITERATIONS = 50000;
        bool solution = false;

        for (int iters = 0; iters < ITERATIONS && !solution; ++iters){
            auto maxIt = max_element(sate.begin(), sate.end());
            auto minIt = min_element(sate.begin(), sate.end());

            if (maxIt == minIt){
                assert(maxIt->totalSum == target);
                solution = true;
            }
            else{
                uniform_int_distribution<> distrib(0, (int)maxIt->size() - 1);
                minIt->add(maxIt->remove(distrib(gen)));
            }
        }

        out << (solution ? "DA" : "NU") << "\n";
    }

    return 0;
}