Cod sursa(job #322857)

Utilizator GheorgheMihaiMihai Gheorghe GheorgheMihai Data 9 iunie 2009 23:26:08
Problema Garaj Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include<stdio.h>
struct point
{
	int c,t;
};
int n,c,nr,min=1999999999;
point v[100002];
int sol[100002];

void read()
{
	freopen("garaj.in","r",stdin);
	freopen("garaj.out","w",stdout);
	scanf("%d%d",&n,&c);
	int i;
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&v[i].c,&v[i].t);
		v[i].t*=2;
		if(v[i].t<min)
			min=v[i].t;
	}
}

int exista(int x)
{
	int s=0,i;
	for(i=1;i<=n;i++)
	{
		if(v[i].t>x)
			break;
		s=s+v[i].c*((int)x/v[i].t);
	}
	return s>=c;
}

int part2(int st, int dr)
{
	int i,j,m,aux,p;
	m=(st+dr)>>1;
	p=sol[m];
	i=st-1;
	j=dr+1;
	while(1)
	{
		do{++i;}while(sol[i]>p);
		do{--j;}while(sol[j]<p);
		if(i<j)
		{
			aux=sol[i];
			sol[i]=sol[j];
			sol[j]=aux;
		}
		else
			return j;
	}
}

void quick2(int st, int dr)
{
	int p;
	if(st<dr)
	{
		p=part2(st,dr);
		quick2(st,p);
		quick2(p+1,dr);
	}
}

void cautare()
{
	int st,dr,m;
	st=min;
	dr=300000;
	while(st!=dr)
	{
		m=(st+dr)>>1;
		if(exista(m))
			dr=m;
		else
			st=m+1;
	}
	int i;
	for(i=1;i<=n;i++)
	{
		if(v[i].t>st)
			break;
		sol[i]=v[i].c*((int)st/v[i].t);
		nr++;
	}
	quick2(1,nr);
	int s=0,nrs=0;
	for(i=1;i<=nr;i++)
	{
		s=s+sol[i];
		nrs++;
		if(s>=c)
			break;
	}
	printf("%d %d\n",st,nrs);
}

int part(int st, int dr)
{
	int i,j,m;
	point p,aux;
	m=(st+dr)>>1;
	p=v[m];
	i=st-1;
	j=dr+1;
	while(1)
	{
		do{++i;}while(v[i].t<p.t);
		do{--j;}while(v[j].t>p.t);
		if(i<j)
		{
			aux=v[i];
			v[i]=v[j];
			v[j]=aux;
		}
		else
			return j;
	}
}

void quick(int st, int dr)
{
	int p;
	if(st<dr)
	{
		p=part(st,dr);
		quick(st,p);
		quick(p+1,dr);
	}
}

int main()
{
	read();
	quick(1,n);
	cautare();
	return 0;
}