Cod sursa(job #441335)

Utilizator catalin_olariOlari Catalin Georgel catalin_olari Data 12 aprilie 2010 21:18:41
Problema Gutui Scor 100
Compilator c Status done
Runda teme_upb Marime 4.18 kb
#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;
    
      for(i=k-1;v[i] > elem && i>=begin;i--)//fac loc elementului si-i caut pozitia
         v[i+1]=v[i];
   
        
          v[i+1]=elem;//inserare
      
      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);     

     gutui=destroy(gutui);//eliberare spatiu alocat gutuielor
     return 0;
}