Cod sursa(job #463133)

Utilizator simona.poilincaSimona Poilinca simona.poilinca Data 14 iunie 2010 17:24:30
Problema Gutui Scor 100
Compilator c Status done
Runda teme_upb Marime 3.26 kb

	/*
	 * Gutu Marius Gabriel
	 * 321CA
	 * 
	 * Proiectarea Algoritmilor
	 * Tema 1
	 * Gutui
	 */
	
	#include <stdio.h>
	#include <stdlib.h>
	#include <math.h>
	
	/* Infinit */
	#define INF	2000000000

	/* Structura unei gutui */
	typedef struct
	{
		long int h;	// inaltimea
		long int w;	// greutatea
	} gutuie;
	
	gutuie *gut;	// vectorul de gutui
	
	// Functie de comparare a doua elemente
	int compare (const void * a, const void * b)
	{
		// sortez dupa greutate
		return ((gutuie*)b)->w - ((gutuie*)a)->w;
	}
		
	int main()
	{
		/* Variabile principale */
		long int 
			N,	// numarul de gutui din copac
			H,	// inaltimea maxima la care ajunge Gigel
			U;	// cu cat se ridica crengile copacului dupa culegerea unei gutui
			
		long int
			gout;	// greutatea maxima a gutuilor pe care le poate culege Gigel
			
		long int 
			i, j, 	// contoare auxiliare
			minh,	// valoare axuliara
			aux;	// valoare axuliara
			
		long int
			*nivel;	// vector de "nivele" pentru gutui == de cate ori ar
					// putea fi luata o anumita gutuie pentru a se incadra
					// in limita impusa de H
		
		// fisierele de intrare si de iesire
		FILE *fin, *fout;
		fin = fopen ("gutui.in","r");
		fout = fopen ("gutui.out","w");
		
		// citim N, H si U
		fscanf(fin,"%ld %ld %ld",&N,&H,&U);
		
		// alocam spatiu pentru vectorul de gutui
		gut	=	(gutuie *) malloc (N*sizeof(gutuie));
		
		// citim perechile corespunzatoare inaltime-greutate pentru 
		// fiecare gutuie
		for (i=0; i<N; i++)
			fscanf(fin,"%ld %ld",&gut[i].h,&gut[i].w);
		
		// setam greutatea maxima pe care o poate obtine Gigel la 0
		gout	=	0;
				
		// sortare vector de gutui cu un algoritm QuickSort, dupa greutate
		qsort(gut, N, sizeof(gutuie), compare);
		
		// setam minimul global la INF
		minh	=	INF;
		
		// pentru fiecare gutuie
		for (i=0; i<N; i++)
		{
			// daca se afla la o inaltime mai mica decat minh
			if (gut[i].h < minh)
				// actualizam minh
				minh = gut[i].h;
		}
		
		// calculam numarul de nivele
		minh = (H-minh)/U+1;
		
		// alocam spatiu pentru vectorul de nivele
		nivel	=	(long int *) calloc ((minh+2),sizeof(long int));

		// initial, nu avem elemente pe niciun nivel
		for (i=1; i<=minh; i++) nivel[i] = -1;

		// pentru fiecare gutuie
		for (i=0; i<N; i++)
		{
			// calculez nivelul
			aux = (H - gut[i].h)/U + 1;
			
			// daca nivelul este mai mare ca 0
			if (aux>0)
			{
				// daca nu avem un element pe nivelul corespunzator
				// punem gutuia pe acel nivel
				if (nivel[aux]==-1) nivel[aux] = i;
				// daca avem deja un element pe nivelul corespunzator
				else
				{
					// punem gutuia pe prima pozitie libera din stanga, 
					// daca aceasta exista
					for (j = aux-1; j>=0; j--)
						if (nivel[j]==-1)
						{
							nivel[j] = i;
							break;
						}
				}
			}
		}
		
		// pentru fiecare nivel
		for (i=1; i<=minh; i++)
		{
			// daca avem o gutuie pe nivelul respectiv
			if (nivel[i]!=-1)
			{
				// care poate fi culeasa (se afla la o inaltime mai mica 
				// decat H)
				if (gut[nivel[i]].h<=H)
				{
					// culeg acea gutuie
					gout += gut[nivel[i]].w;
					// decrementez H (in loc sa urc toate gutuile)
					H -= U;
				}
			}
		}
		
		// afisez greutatea maxima pe care o poate culege Gigel in fisier
		fprintf (fout,"%ld\n",gout);
		
		// inchid fisierele
		fclose(fin);
		fclose(fout);
		return 0;
	}