Cod sursa(job #210779)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 29 septembrie 2008 01:14:47
Problema Lapte Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
using namespace std;

#include <algorithm>
#include <vector>
#include <cstdio>
#include <utility>
#include <functional>

#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define N_MAX 1<<7
#define o first.first
#define f first.second
#define s second.first
#define poz second.second
#define IN "lapte.in"
#define OUT "lapte.out"
#define II inline

vector< pair< pair<int,int> ,pair<int,int> > > V(N_MAX),S(N_MAX);
char buffer[1<<10];
int rez(1<<29),VA,VB,K(-1),N,L;

II int read()
{
	int aux(0);
	for(;buffer[K] > '9' || buffer[K] < '0';++K);
	for(;buffer[K] <= '9' && buffer[K] >= '0';++K)
		aux = aux * 10 + buffer[K] - '0';
	return aux;
}

II void scan()
{
	freopen(IN, "r",stdin);
	fread(buffer,1,1<<10,stdin);
	fclose(stdin);
	N = read();
	L = read();
	V.resize(N+1);
	S.resize(N+1);
	FOR(i,1,N)
		V[i].f = read(),
		V[i].s = read(),
		V[i].poz = i;
	sort(V.begin()+1, V.end() );
}

II void sort1()
{
	FOR(i,1,N)
		V[i].o = V[i].f;
	sort(V.begin()+1, V.end() );
	FOR(i,1,N)
		S[i].poz = V[i].poz;
}

II void sort2()
{
	FOR(i,1,N)
		V[i].o = V[i].f;
		
	sort(V.begin()+1, V.end() );
	std::reverse(V.begin()+1, V.end());		
	FOR(i,1,N)
		S[i].poz = V[i].poz;
}

II void sort3()
{
	FOR(i,1,N)
		V[i].o = V[i].s;
	sort(V.begin()+1, V.end() );
	FOR(i,1,N)
		S[i].poz = V[i].poz;
}

II void sort4()
{
	FOR(i,1,N)
		V[i].o = V[i].s;
	sort(V.begin()+1, V.end() );
	std::reverse(V.begin()+1, V.end());		
	FOR(i,1,N)
		S[i].poz = V[i].poz;
}	

II bool ok(int T)
{
	int a = L,b = L;
	int Va = VA,Vb = VB;
	
	FOR(i,1,N)
	{
		if(a == b) // daca mai sunt acelasi nr de litri de baut
		{
			Va -= V[i].f,
			Vb -= V[i].s;
			if(Va + V[i].f > Vb + V[i].s) //daca cei ramasi beau mai rapid B decat A
			{
				S[i].f = min(T / V[i].f,a);
				a -= min(T / V[i].f,a);
				S[i].s = min( (T - S[i].f * V[i].f) / V[i].s,b);
				b -= min( (T - S[i].f * V[i].f) / V[i].s,b); 
				continue;
			}
			//daca cei ramasi beau mai rapid A decat B
			S[i].s = min(T / V[i].s,b);
			b -= min(T / V[i].s,b);
			S[i].f = min( (T - S[i].s * V[i].s) / V[i].f,a);
			a -= min( (T - S[i].s * V[i].s) / V[i].f,a); 
			continue;
		}	
		if(b < a) //daca sunt mai putini litri B de baut decat A 
		{	
			S[i].f = min(T / V[i].f,a);
			a -= min(T / V[i].f,a);
			S[i].s = min( (T - S[i].f * V[i].f) / V[i].s,b);
			b -= min( (T - S[i].f * V[i].f) / V[i].s,b); 
			continue;
		}
		//daca sunt mai putini litri A de baut decat B
		S[i].s = min(T / V[i].s,b);
		b -= min(T / V[i].s,b);
		S[i].f = min( (T - S[i].s * V[i].s) / V[i].f,a);
		a -= min( (T - S[i].s * V[i].s) / V[i].f,a); 
	}	
	if(a>0 || b>0)
		return false;
	return true;
}

II void print();
II void solve()
{
	FOR(i,1,N)
		VA += V[i].f,
		VB += V[i].s;
		
	int T,step;
    for(step = 1; step <= 100; step <<= 1);
    for(T = 1; step; step >>= 1)
		if(T + step <= 100 && !ok(T+step-1) )
			T += step;
	ok(T);
	if(T > rez)
		return;
	rez = T;
	sprintf(buffer,"%d\n",T);

	FOR(i,1,N)
		swap(S[i].f,S[i].poz);
	sort(S.begin()+1,S.end());
	print();
}	

II void print()
{
	FOR(i,1,N)
		sprintf(buffer,"%s%d %d\n",buffer,S[i].poz,S[i].s);
	freopen(OUT,"w",stdout);
	printf("%s",buffer);
	fclose(stdout);
}

int main()
{
	scan();
	
	sort1();
	solve();
	
	sort2();
	solve();
	
	sort3();
	solve();
	
	sort4();
	solve();
	return 0;
}