Pagini recente » infoarena 2 | Cod sursa (job #1295010) | Cod sursa (job #865271) | Cod sursa (job #1883370) | Cod sursa (job #441637)
Cod sursa(job #441637)
/*
* 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;
}