/* gutui.c*/
#include <unistd.h> /* pentru open(), exit() */
#include <errno.h> /* perror() */
#include <stdlib.h>
#include <stdio.h>
#define INF 32000
#define MAX(a,b) ((a)>(b) ? (a) : (b))
#define MIN(a,b) ((a)<(b) ? (a) : (b))
void fatal(char * mesaj_eroare)
{
perror(mesaj_eroare);
exit(1);
}
typedef struct gutuia {
int greutate;
int inaltime;
} Tgutuie, *Agutuie;
Tgutuie gutui[100000];
Tgutuie mergeaux[100000];
int N,H,U;
int n;
static void ReadFile()
{
FILE *file_in= fopen("gutui.in", "r");
int copiat;
/*citim N (numarul de gutui din copac)*/
if(!file_in) printf("avem o mare problema\n");
copiat=fscanf(file_in, "%i",&N);
if(!copiat) fatal("eroare la citire N din fisier");
/* H (inaltimea maxima la care ajunge Gigel)*/
copiat=fscanf(file_in, "%i",&H);
if(!copiat) fatal("eroare la citire H din fisier");
/*U (cu cat se ridica crengile copacului dupa culegerea unei gutui)*/
copiat=fscanf(file_in, "%i",&U);
if(!copiat) fatal("eroare la citire U din fisier");
int i,g,h;
int j=0;
for(i=0;i<N;i++){
copiat=fscanf(file_in, "%i",&h);
if(!copiat) fatal("eroare la citire inaltime din fisier");
copiat=fscanf(file_in, "%i",&g);
if(!copiat) fatal("eroare la citire greutate din fisier");
if((H-h)/U+1>0)
{
gutui[j].inaltime=(H-h)/U+1;
gutui[j].greutate=g;
j++;
}
}
n=j;
fclose(file_in);
}
int compare_by_height_and_weight (const void * a, const void * b)
{
if(((Tgutuie *)b)->inaltime == ((Tgutuie *)a)->inaltime)
return ( ((Tgutuie *)b)->greutate - ((Tgutuie *)a)->greutate );
return ( ((Tgutuie *)b)->inaltime - ((Tgutuie *)a)->inaltime );
}
/*static void AfisareGutui(Agutuie g, int n)
{
int i=0;
printf("\n------\n");
while(i<n){
printf("%i %i\n",g->inaltime,g->greutate);
g++;
i++;
}
printf("\n------\n");
}*/
static int alegere_gutui(Agutuie gutui)
{
qsort (gutui, n, sizeof(Tgutuie), compare_by_height_and_weight);
// AfisareGutui(gutui,n);
long greutate=0;
Agutuie p,q,aux;
int i;
//pregatire date pas initial
p=gutui;
q=gutui;
while(q->inaltime==p->inaltime&& q-gutui<n) q++;
while(q-gutui<n){
//fructe ce vor fi culese
for(i=0;i<(p->inaltime-q->inaltime);i++){
greutate+=p->greutate;
// printf("%i+",p->greutate);
p++;
}
aux=p;
//pregatirea date pentru pasul urmator
while(aux<q&&aux-p<q->inaltime) {aux->inaltime=q->inaltime; aux++;}
// AfisareGutui(gutui,n);
// printf("dupa mem cpy:");
if(q-p>(p->inaltime)){
memcpy ((void*)(q- (p->inaltime)), (const void*)p, (p->inaltime)*sizeof(Tgutuie));
p=q-p->inaltime;
}
// AfisareGutui(gutui,n);
aux=q;
while(q->inaltime==p->inaltime&& q-gutui<n&& (q-aux)<p->inaltime) q++;
qsort (p, q-p, sizeof(Tgutuie), compare_by_height_and_weight);
// printf("dupa sortare:%i %i %i",p->inaltime,p->greutate,q-p);
// AfisareGutui(gutui,n);
//merge(p,i,aux,q-aux);
}
//culegerea ultimelor fructe
for(i=0;i<p->inaltime;i++){
greutate+=p->greutate;
// printf("%i+",p->greutate);
p++;
}
return greutate;
}
int main(void)
{
ReadFile();
FILE *file_out= fopen("gutui.out", "w");
fprintf(file_out,"%i\n",alegere_gutui(gutui));
fclose(file_out);
// getchar();
return 0;
}