Cod sursa(job #441438)

Utilizator IceyLiviu Grandl Icey Data 12 aprilie 2010 22:11:34
Problema Gutui Scor 60
Compilator c Status done
Runda teme_upb Marime 5.91 kb
#include<stdio.h>
#include<stdlib.h>

typedef struct gut{
	int inal, greut;
}gut;


	void afisare(gut *a, int n)
	{
		printf("\n");
		int i;
		for(i =0; i< n; i++)
			printf("%d Inaltime %d, Greutate %d\n", i, a[i].inal,a[i].greut); 
	}

	int compare(const void* x,const void* y)
	{
	    return (((gut*)x)->inal) <= (((gut*)y)->inal);
	}
	
	int h,u;
	
	int compare1(const void* x, const void* y)
	{
		if(((h-(((gut*)x)->inal))/u)!=((h-(((gut*)y)->inal))/u))
			if ((((gut*)x)->inal) < (((gut*)y)->inal))
						return 1;
			else
						return -1;
		else
			   return (((gut*)x)->greut) <= (((gut*)y)->greut);
			
	}	
	

	int main()
	{
	FILE *f, *fo;
	f = fopen("gutui.in", "r");
	fo = fopen("gutui.out", "w");
	int n, i, j;
	gut *a = NULL;

	fscanf(f, "%d", &n);
	fscanf(f, "%d", &h);
	fscanf(f, "%d", &u);

	a = (gut*)malloc(n * sizeof(gut));
	for(i = 0; i < n; i++)
	{
		fscanf(f, "%d", &a[i].inal);
		fscanf(f, "%d", &a[i].greut);
	}

//	afisare(a,n);
	qsort(a, n, sizeof(gut), compare);//ordonare descresc dupa nivele, iar daca sunt pe acelasi nivel, dupa greutate

//	afisare(a,n);
			
	// nr cate nivele sunt folosite, si cate gutui sunt pe fiecare nivel, pentru a aloca vectori pt fiecare nivel
	//
	//h inaltimea maxima

	int *cos;
	cos = (int*)malloc(n*sizeof(int));
	for(i = 0; i <n; i++)
		cos[i] = 0;

	
	int min, nec =0,poz = 0;
//	int h1 = h, nr_niv = 0;
	
	while(a[nec].inal > h && nec<n) //daca nu pot fi culese, sar peste ele ca nu ma intereseaza
		nec++;
//	printf("\nSunt %d gutui care un pot fi culese din start\n", nec);
	int k = 0;


	for(i = nec; i <n; i++)
		if(a[i].inal <= h)
		{
			cos[k++] = a[i].greut;
			for(j = i; j <n;j++)
				a[j].inal+=u;
			
		}
		else
		{
			min = cos[0];
			for(j = 0; j < k; j++)
				if(min > cos[j])
				{
					min = cos[j];
					poz = j;

				}
//			printf("\nMinimul este %d, pe pozitia %d iar gutuia %d\n",min,poz,a[i].greut); 
			if(a[i].greut > min)
				cos[poz] = a[i].greut;
//				int x;
//			for(x = 0; x < k ;x++)
//				printf("%d ",cos[x]);
//			printf("\n");

		}
	// printf("\n In cos am %d gutui \n",k);
	/*
	int *nr;
	nr = (int*)malloc(n * sizeof(int));
	for (j = 0; j < n ; j++)		//initializez cu 0
		nr[j] = 0;					//nr de nivele maxim (nr de gutui)
	

	while(i < n)						//complexitate O(N) - > pentru a vedea cate gutui sunt pe nivel, respectiv cate nivele sunt folosite
	{
		while((a[i].inal > (h1-u)) &&(a[i].inal <= h1) && i < n)
		{
			i++;
			nr[nr_niv] ++;
		}
			printf("Sunt %d gutui pe niveul %d\n",nr[nr_niv], nr_niv);
		nr_niv++;
		h1 = h1 - u;

	}
	for(i = 0; i <nr_niv;i++)
		printf("%d ", nr[i]);

	printf("\nSunt %d nivele, dintre care %d folosite\n",(h-a[n-1].inal)/u+1  ,nr_niv); 

	//contoare
	//
	i = 0; //nr de gutui, ca sa stiu unde ma opresc
	int g = 0 ; //nr de gutui pe care terbuie sa le tot iau

	int in;
	int *col; //gutuile colectate
	col = (int*)malloc(n * sizeof(int*));
	for(i = 0; i<n;i++)
		col[i] = 0;
	
	
	i = 0;
	int nx = 0,niv;

	while(a[i].inal > h && i <n)
		i++;
	printf("%d gutui \n",i);

	int loc = 0,aux;	//adun nr de gutui de pe fiecare nivel


	printf("Debugging:\n");

	for( niv = 0; niv < nr_niv && i < n; niv++)	//parcurg nivelele
	{	
		printf("Nr gutui ce trebuie tot luate ste %d \n",g);
		loc += nr[niv];
		printf("Sunt pe nivelul %d, si nr de gutui maxime pana aci este %d\n", niv, loc);

		if(nr[niv] == 0)				//daca pe nivelul curent nu am gutui
			g++;						//pun la gutui "restante", adica cate trebuie sa iau in plus de pe urm nivele
		else							//daca nu am gutui pe nivelul curent
			if(g == 0)					//daca nu am gutui restante			
			{
				printf("\n Am luat gutuia de greutate %d \n",a[i].greut);
				col[nx] = a[i].greut;	//iau prima gutuie si o pun in cos
				nx++;					//cresc cate gutui am pus in cos
				i += nr[niv];			//si trec la urmatorul nivel..ca nr de gutui
			
				printf("Am luat prima gutuie de pe nivelul %d, si i-u urca pana la %d de greutate %d\n", niv, i,a[i].greut);
				printf("Nr gutui culese pana acu este %d \n", nx);
			}
			else
			{	aux = nr[niv];
				printf("Am gutui restante de luat %d,gutui per nivel %d\n", g,aux);
				while( g > 0 || aux > 0)	//cat timp mai am gutui de luat de pe nivelul curent, sau mai am gutui pe nivel
				{
						col[nx] = a[i].greut;	//le adaug la cos
						nx ++;					//cresc nr gutui puse in cos
						aux --;				//scad nr de gutui per nivel culese
						i++;					//trec la urmatoarea gutuie
						g--;					//scad nr de gutui restante
					printf("Gutui restante ramase %d , gutui culese %d, gutuia la care sunt %d, gutui ramase per nivel %d\n",g,nx,i,aux);
				}
				if( g == 0 && aux > 0)		//daca am terminat nr de gutui restante de cules, dar mai am pe nivel
				{
					col[nx] = a[i].greut;//mai culeg una de pe  nivelul curent, 
					nx++;
					while(i<loc)		//cresc i-u pana depasesc nivelul
						i++;
					printf("Gutui restante nu sunt, sunt la gutuia %d \n",i);
				if(aux == 0)
					g++;
			//	if(g < 0)
			//		g = 0;
				}
			}

	}
*/
/*
	while(i < n)
	{
		in = (h - a[i].inal)/u;	//nivelul pe care este gutuia i
		if(in == 0)		//daca am nivelul initial
		{
			if(nr[in] != 0)	//daca nivelul un este gol
			{
				col[nx++] = a[i].greut;		//iau prima gutuie, ca e cea mai grea
				i += nr[in];	//trec peste celelalte de pe acest nivel
			}
			else
				g = 1;		//daca nivelul este gol, inseamna ca trebuie luata de mai jos in plus cu o gutuie
		}
		else				//daca nu sunt pe primul nivel
		{	printf("si aci\n");
			if(nr[in] != 0)	//daca nivelul este gol
			{
				if( g == 0)	//daca nu am gutui de luat restante
				{
					col[nx++] = a[i].greut;	//iau prima gutuie de aci
					i += nr[in];	
				}
				else
					while( g > 0 || nr[in] > 0)		//daca mai am gutuie de luat, cat timp mai am restante, sau cat timp mai am gutui pe nivel, le pun in cos
					{
						col[nx++] = a[i].greut;
						i++;
					}
			}
			else
					g++;	//daca nivelul este go, mai adaug gutui restante
		}
	}
*/
	int s = 0;
	for(i =0; i<k; i++)
	{	
		s += cos[i];
	}

//	printf("Suma maxima este: %d \n",s);
	fprintf(fo, "%d",s);

free(a);
fclose(f);
fclose(fo);
return 0;
	
	}