#include<stdio.h>
#include<stdlib.h>
typedef struct //structura
{
long inaltime,greutate;
}fruct;
long N;//numarul de gutui
long H,U;//inaltimile
fruct *gutui;//gutuile
fruct* destroy(fruct *gutui) //functia care elibereaza spatiul alocat tablourilor
{
free(gutui);
gutui=NULL;
return gutui;
}
short citire()//functia de citire
{
FILE *f=fopen("gutui.in","rt"); //deschidere fisier
long i;
if(!f)
{//esec
printf("File not found!");
return -1;
}
fscanf(f,"%li%li%li",&N,&H,&U);//numarul de gutui si cele 2 inaltimi
gutui=(fruct*)calloc(N,sizeof(fruct));//alocare spatiu pentru N gutui
if(!gutui)
{//esec
printf("Alocare esuata");
return -2;
}
for(i=0;i<N;i++)
fscanf(f,"%li%li",&gutui[i].inaltime,&gutui[i].greutate); //citire fiecare gutuie
fclose(f);//inchidere fisier
return 0;
}
int sort_function(const void *a,const void *b)//functia de sortare trimis ca parametru in Qsort
{
fruct *A=(fruct*)a;
fruct *B=(fruct*)b;
return B->inaltime - A->inaltime;//sortare dupa inaltime DESC
}
long cautare_binara(long *v,long s,long d,long elem)//returneaza pozitia la care trebuie inserat 'elem' asa incat vectorul v sa ramana sortat
{
if(s < d)//daca mai am unde cauta
{ if(v[ (s+d)/2 ] > elem)//daca elementul este mai mic decat cel de la jumatatea subvectorului
return cautare_binara(v,s,(s+d)/2,elem); //caut in jumatatea stanga
else
if(v[ (s+d)/2 ] < elem)
return cautare_binara(v,(s+d)/2+1,d,elem); //caut in jumatatea dreapta
else
return (s+d)/2; //elementul exista deja deci am gasit si pozitia
}
return s;//pozitia
}
long* actualizeaza(long *v,long begin,long k,long elem)
//primeste ca parametru un vector,pozitiile de start si de sfarsit ( begin si k) si elementul care se insereaza
//functia returneaza vectorul dupa ce s-a inserat valoarea 'elem'
{long i;
// long poz=cautare_binara(v,begin,k-1,elem),i;//pozitia la care se face inserarea
if(begin == k)
v[k]=elem;
else
if(v[k-1] < elem)
v[k]=elem;
else
{
for(i=k-1;v[k] > elem && i>=begin;i--)//fac loc elementului
v[i+1]=v[i];
// if(k==0 || begin==k || elem < v[poz]) //cand vectorul este gol sau cand elementul este mai mic se insereaza in stanga
// v[poz]=elem;
// else
v[i+1]=elem;//altfel se insereaza in dreapt
}
return v;//returnare vector actualizat
}
long solve()
{
long i,k=0,*v,begin=0;
long G=0;
v=(long*)calloc(N,sizeof(long));//alocare spatiu pentru vector ( folosim maxim N )
if(!v)
return -1;
for(i=0;i<N;i++)
if( gutui[i].inaltime <= H)//daca ajung la gutuie
{
v=actualizeaza(v,begin,k++,gutui[i].greutate);//adaug greutatea acesteia in vector
H-=U;//inaltimea scade
G+=gutui[i].greutate;//calculez greutatea totala
}
else//daca nu pot ajunge la o anume gutuie
if(begin < k)//si daca am cules macar o gutuie pana acuma
if( gutui[i].greutate > v[begin] )//si daca greutatea acesteia este mai mare decat minimul din vector
{
//atunci facem urmatoarea modificare: scoatem gutuia cea mai mica din vector, si o introduce pe aceasta.
G-=v[begin];//scoatem din G greutatea acesteia
begin++;//o eliminam
v=actualizeaza(v,begin,k++,gutui[i].greutate);//adaugam noua gutuie ( la care Gigel va ajunge pentru ca a renuntat la o alta gutuie)
G+=gutui[i].greutate;//adaug greutatea acesteia la suma
//de data aceasta H nu mai scade pentru ca am facut o inlocuire
}
free(v);//eliberare spatiu alocat vectorului
return G;//returneaza rezultatul
}
int main()
{
if( citire() != 0) //citire
return -1;
qsort((void*)gutui,N,sizeof(fruct),sort_function);//sortarea gutuielor dupa inaltime
FILE *f=fopen("gutui.out","wt");
fprintf(f,"%li",solve());//scriere in fiesier
fclose(f);
long i,v[50],x,j;
for(i=0;i<100;i++)
{
scanf("%li",&x);
actualizeaza(v,0,i,x);
printf("\n");
for(j=0;j<=i;j++)
printf("%li ",v[j]);
getch();
}
gutui=destroy(gutui);//eliberare spatiu alocat gutuielor
return 0;
}