Cod sursa(job #437522)

Utilizator DetudaArthur Koestler Detuda Data 9 aprilie 2010 20:42:29
Problema Gutui Scor 20
Compilator c Status done
Runda teme_upb Marime 3.33 kb
#include <stdio.h>
#include <string.h>

void swap (long a, long b)
{
	long aux;
	aux=a;
	a=b;
	b=aux;
}

	// nr gutui, inaltimea maxima, inaltarea, rezultatul final
	long n, hi, u, smax=0;
	// inantimea fiecarei gutui si greutatea
	long h[100001], w[100001], i, j, aux, max, im;
	long hmin, nrs, k, s[100001], contor, x, y;

//imparte fructele in sectoare
void sectoare()
{
	for(k=1; k<=nrs; k++)
	for(i=0; i<n; i++)
	if(h[i]+k*u>hi && h[i]+(k-1)*u<=hi)
	{
		s[i]=k;
		printf("sectoare(): fructul %ld de greutate %ld este pe sectorul %ld\n", i, w[i], k);
	}
}

//indicele fructului cu greutate maxima de pe sectorul k
long imax (long k)
{
	im=-100;
	max=-300;
	for(i=0; i<n; i++)
	if(w[i]>max && s[i]==k && h[i]<=hi)
	{
		im=i;
		max=w[i];
	}
	return im;	
}

//indicele fructului cu greutate maxima de pe sectoarele 1-k
long imax1 (long k)
{
	im=-100;
	max=-300;
	for(i=0; i<n; i++)
	if(w[i]>max && 1<=s[i] &&s[i]<=k  && h[i]<=hi)
	{
		im=i;
		max=w[i];
	}
	return im;	
}

// verifica daca pe sectorul k sunt cel putin k elemente mai grele decat elementul x
int verifica(long x, long k)
{
	contor=0;
	for(i=0; i<n; i++)
	if(w[i]>=w[x] && s[i]==k  && h[i]<=hi)
	contor++;
	if(contor>=k)
	return 1;
	else
	return 0;
}

//culege fructul cu indicele y, cu toate urmarile
void culege(long y)
{
if(y>=0 && w[y]>=0)
{
	smax+=w[y];
	printf("culege(): am ales fructul cu greutatea %ld\n", w[y]);
	w[y]=-547;
	for(i=0; i<n; i++)
	{
		h[i]+=u;
		if(h[i]>hi)
		w[i]=-547;
	}
}
}
	

int main()
{
	int done;
	FILE *f=fopen("gutui.in", "r");
	FILE *g=fopen("gutui.out", "w");
	fscanf(f, "%ld %ld %ld", &n, &hi, &u);

	for(i=0; i<n; i++)
	fscanf(f, "%ld %ld", &h[i], &w[i]);
/*	for(i=0; i<n; i++)
	printf("fructul %ld are inaltimea %ld si greutatea %ld\n", i, h[i], w[i]);
*/
	//sortam descrescator fructele, in functie de inaltime
	//trebuie inlocuit cu quicksort, de exemplu
	for(i=0; i<n-1; i++)
	for(j=i+1; j<n; j++)
	if(h[i]<h[j])
	{
	//swap(h[i], h[j]);
	//swap(w[i], w[j]);
	aux=h[i];
	h[i]=h[j];
	h[j]=aux;
	aux=w[i];
	w[i]=w[j];
	w[j]=aux;
	}
	printf("Dupa quicksort: \n");
	for(i=0; i<n; i++)
	printf("fructul %ld are inaltimea %ld si greutatea %ld\n", i, h[i], w[i]);
	
	hmin=h[n-1];
	printf("hmin este: %ld\n", hmin);
//pana aici sigur e bine
	nrs=(hi-hmin)/u+1;
	printf("numarul de sectoare este: %ld\n", nrs);

	//the core shit
	done=0;
	//cat timp n-am terminat
	while(done==0)
	{
		//(re)impartim fructele in sectoare, in functie de inaltimile curente
		sectoare();
		k=nrs;
		while(k>0 && imax(k)<0)
			k--;
		//ajungem la cel mai de jos sector cu fructe
		if(k==0)
			done=1;
		else
		{
			while(k>0)
			{
				y=imax(k);	//e deja >0
				if(k>1)
				x=imax1(k-1); 
				else 
				{
					x=-100;
					w[x]=-547;
				}
				printf("fructul cel mai greu de pe sectoarele superioare este %ld \n", w[x]);
				// x e indicele celui mai greu element de pe sectoarele 1-(k-1)
				// daca nu exista elemente pe sectoarele de mai sus
				// sau daca exista x>0 dar sunt k elemente mai grele decat el pe sectorul k
				if( x<0 || ( x>=0 && verifica(x, k) ) )
				{
					culege(y);
					break;
				}
				else
				k--;
			} // oare ar mai trebui adaugat ceva?
			done=1;
			for(i=0; i<n; i++)
			if(h[i]<=hi && w[i]>0)
			{
				printf("fructul cu greutate %ld inca mai poate fi ales\n", w[i]);
				done=0;
			}
		}
	}
		
	printf("%ld\n", smax);
	fprintf(g, "%ld", smax);
	
	fclose(f);
	fclose(g);
	return 0;
}