Cod sursa(job #440145)

Utilizator veraconstVeronica Constantinoaia veraconst Data 11 aprilie 2010 22:17:55
Problema Gutui Scor 80
Compilator c Status done
Runda teme_upb Marime 3.45 kb
//NUME: CONSTANTINOAIA VERONICA
//GRUPA: 323 CA

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//structura unei gutui

typedef struct gut
{	
	long int iteratie; //numarul de iteratii/pasi/"culegeri"/"inaltari" necesari pentru ca o gutuie sa depaseasca h 
	long int greutate; //greutatea unei gutui
} gutui;

int compare_desc (const void * a, const void * b)
/** functie comparator folosita la sortarea descrescatoate in functie de greutate
   */
{
    gutui *g1 = (gutui *)a;
    gutui *g2 = (gutui *)b;
    return ( g2->greutate - g1->greutate );
}

int iteratii(long int a,long int b)
/** functie pentru calcularea numarului de iterarii pentru fiecare gutuie -> complexitate temporala O(1)
  *@param a,b 
  *@return iteratii
  */
{
	ldiv_t result;
	result = ldiv(a,b);
	return result.quot+1;
}

void inalta (gutui *a,long int pi, long int n,long int iter)
/** functie ce inalta gutuile la fiecare culegere (<=> scade cu 1 iteratiile gutuilor cu iteratii mai mari sau egale cu cea culeasa) -> complexitate temporala O(n^2)
  *@param a-> vectorul de gutui
  *@param pi ->pozitia dupa care se incepe inaltarea
  *@param n -> numarul de elemente din vector
  *@param iter -> ieteratia gutui culese
  *@return void
  */
{
	long int i;
	for (i=pi;i<n;i++)
		if (a[i].iteratie>=iter)
			a[i].iteratie--;
	
}

long int max_iter(gutui *a,long int n)
/** functie ce gaseste iteratia maxima dintr-un vector de gutui -> complexitate temporala O(n)
   *@param a -> vectorul de gutui
   *@param n -> numarul de elemente din vector
   *@return max -> numarul de iteratii maxim din vector
   */
{
	long int i,max=a[0].iteratie;
	for (i=1;i<n;i++)
		if (a[i].iteratie>max)
			max=a[i].iteratie;
	return max;
}

int main()
{
	FILE *f=fopen ("gutui.in","r");
	FILE *g=fopen ("gutui.out","w");
	
	gutui *a;
	long int n,h,u,i,inaltime,greutate,nr=0;
	fscanf(f,"%ld %ld %ld",&n,&h,&u);

	a=(gutui*)malloc(n*sizeof(gutui)); 
	long int gmax;

	// citirea gutuilor si initializarea structurii gutui

	for (i=0;i<n;i++)				//O(n)
	{
		fscanf(f,"%ld %ld",&inaltime,&greutate);			
		if (inaltime<=h)  //se retin in vector doar gutuile viabile pentru cules: cele care au inaltimea initiala mai mica sau egala ca h 
		{	
			a[nr].greutate=greutate;			
			a[nr].iteratie=iteratii(h-inaltime,u); //in loc de a retine inaltimea initiala a unei gutui, se retine iteratia initiala= (catul impartirii inaltimii maxime h la diferenta dintre h si inaltimea initiala a unei gutui) + 1
			nr++;
		}
	}
	n=nr;
	
	qsort(a,n,sizeof(gutui),compare_desc); //vectorul de gutui se sorteaza descrescator in functie de greutate      O(nlogn)

	for (i=0;i<n;i++)
		printf ("%ld %ld\n",a[i].iteratie,a[i].greutate);

	long imax=max_iter(a,n); //se retine iteratia maxima din vectorul de gutui <=> numarul maxim de culegeri care pot fi efectuate
	gmax=0;
	long int j=0; //initial avem 0 gutui culese
	
	//se parcurge vectorul de gutui sortate in functie de greutate; 
	for (i=0;(i<n)&&(j<imax);i++)
	{
		if (a[i].iteratie>0) //fiecare gutuie cu iteratia mai mare ca 0 este adaugata greutatii maxime (<-> se culege), 
		{
			gmax=gmax+a[i].greutate;
			j++; //crestem numarul de gutui culese cu 1
			inalta(a,i+1,n,a[i].iteratie); //pentru toate gutuile ce urmeaza, daca au iteratia mai mare sau egala cu iteratia gutui culese, se scade 1 din iteratie (se "inalta")
		}
	}	
	//parcurgerea se opreste daca au fost terminate gutuile sau daca a fost atins numarul maxim de gutui ce pot fi culese

	fprintf (g,"%ld\n",gmax);

	free(a);
	fclose(f);
	fclose(g);

	return 0;
}