Cod sursa(job #586089)

Utilizator freak93Adrian Budau freak93 Data 30 aprilie 2011 13:39:01
Problema Fabrica Scor 20
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.76 kb
#include <fstream>
#include <set>

using namespace std;

const char iname[] = "fabrica.in";
const char oname[] = "fabrica.out";
const int maxn = 100005;

ifstream f(iname);
ofstream g(oname);

unsigned int a[maxn], b[maxn], ta[maxn], timp[maxn];
unsigned int start[maxn], finish[maxn];

int main() {
	int N, M, K;
	f >> N >> M >> K;

	for (int i = 1; i <= M; ++i)
		f >> a[i], ta[i] = 0;

	for (int i = 1; i <= K; ++i)
		f >> b[i];
    //Terminam cu turnarea
	set< pair<int, int> > S;
	for (int i = 1; i <= M; ++i)
		S.insert(make_pair(a[i], i));
	
	for (int i = 1; i <= N; ++i) {
		int v = S.begin() -> second;
		timp[i] = S.begin() -> first;

		S.erase(S.begin());
		ta[v] += a[v];
		S.insert(make_pair(ta[v] + a[v], v));
	}

	g << timp[N] << " ";

	//Pregatirm sigilarea
	set <pair <int, int> > liber;
	S.clear();
	for (int i = 1; i <= K; ++i)
		S.insert(make_pair(b[i], i));
	
	//Si sigilam
	for (int i = N; i > 0; --i) {
		//Prima bere
		//fprintf(stderr, "%d -> ", i);
		if (liber.size() == 0) {
			int v = S.begin() -> second;
			S.erase(S.begin());
			liber.insert(make_pair(timp[i] - b[v], v));
			start[v] = timp[i] - b[v];
			finish[v] = timp[i] + b[v];
			//fprintf(stderr, "Prima %d -> %d\n", v, finish[v]);
			continue;
		}

        //Mai folosim un procesor nou
		int procesor = liber.rbegin() -> second;
		int libertate = liber.rbegin() -> first;
		int timpnou = finish[procesor];
		if (start[procesor] < timp[i] && libertate < timp[i])
			timpnou += timp[i] - libertate;
		if (S.size() > 0 && timpnou >= timp[i] + b[S.begin() -> second]) {
			int v = S.begin() -> second;
			S.erase(S.begin());
			liber.insert(make_pair(timp[i] - b[v], v));
			start[v] = timp[i] - b[v];
			finish[v] = timp[i] + b[v];
			//fprintf(stderr, "Nou %d -> %d\n", v, finish[v]);
			continue;
		}

		//Folosim ceva de la libere
		liber.erase(*liber.rbegin());
		if (start[procesor] >= timp[i]) {
			libertate -= b[procesor];
			start[procesor] = timp[i] - b[procesor];
			liber.insert(make_pair(libertate, procesor));
			//fprintf(stderr, "Libere jos %d -> %d %d\n", procesor, start[procesor], finish[procesor]);
			continue;
		}
		
		//Ne ajunge libertate
		if (libertate >= timp[i]) {
			libertate -= b[procesor];
			start[procesor] = timp[i] - b[procesor];
			liber.insert(make_pair(libertate, procesor));
			//fprintf(stderr, "Ne ajunge %d -> %d\n", procesor, finish[procesor]);
			continue;
		}

		//Nu ne ajunge
		finish[procesor] += timp[i] - libertate;
		libertate = timp[i] - b[procesor];
		start[procesor] = timp[i] - b[procesor];
		liber.insert(make_pair(libertate, procesor));
		//fprintf(stderr, "Nu ne ajunge %d -> %d\n", procesor, finish[procesor]);
	}
	unsigned rez = 0;
	for (set< pair<int, int> >::iterator it = liber.begin(); it != liber.end(); ++it)
		rez = max(rez, finish[it -> second]);
	g << rez << "\n";
}