Cod sursa(job #441319)

Utilizator catalin_olariOlari Catalin Georgel catalin_olari Data 12 aprilie 2010 21:10:27
Problema Gutui Scor 0
Compilator c Status done
Runda teme_upb Marime 4.77 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;
    //  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;
}