Cod sursa(job #438279)

Utilizator radu.comanRadu Coman - UPB radu.coman Data 10 aprilie 2010 17:17:33
Problema Gutui Scor 0
Compilator c Status done
Runda teme_upb Marime 3.96 kb
#include <stdio.h>
#include <stdlib.h>

typedef struct{
        int inaltime, greutate;
        } Gutui;


// Functii pentru merge sort

void merge(Gutui *v, Gutui *aux, int inceput, int sfarsit, int mijloc, int u)
{
     int i, j = mijloc, contor = inceput;
     for (i = inceput; i < mijloc; i++)
     aux[i] = v[i];
     i = inceput;
     while (i < mijloc && j < sfarsit)
     if (aux[i].inaltime < v[j].inaltime) v[contor++] = aux[i++];
        else
            if (v[j].inaltime < aux[i].inaltime) v[contor++] = v[j++];
               else
                   if (aux[i].greutate > v[j].greutate) v[contor++] = aux[i++]; 
                      else
                          v[contor++] = v[j++];
     for (;i < mijloc; v[contor++] = aux[i++]);
     return;
}                  


void merge_sort_aux(Gutui *v, Gutui *r, int i, int j, int u)
{
     if (j-i == 1) return;
     int m = (i + j) / 2;
     merge_sort_aux(v, r, i, m, u);
     merge_sort_aux(v, r, m, j, u);
     merge(v, r, i, j, m, u);     
}

int merge_sort(Gutui *v, int i, int j, int u)
{
    Gutui *aux = (Gutui*)malloc(j * sizeof(Gutui));
    if(!aux) return 0;
    merge_sort_aux(v, aux, i, j, u);
    free(aux);
    return 1;
}


// Functie care cauta minimul dintr-un sir

void search_min(int *v, int *min_ind, int *min, int j)
{
     int i;
     for (i = 0; i < j; i++)
         if (*min > v[i]) {*min = v[i]; *min_ind = i;}
         
}


void insert_heap(Gutui *v, int inalt, int *sf_heap, int *inc_vector, int n)
{
     int i = 0, j;
     Gutui aux;
     for (; (*inc_vector) < n && v[(*inc_vector)].inaltime == inalt;(*inc_vector)++, (*sf_heap)++)
     {
         v[(*sf_heap)] = v[(*inc_vector)];
         for (i = (*sf_heap);i > 0; i = j)
         {
             j = (i-1)/2;
               if (v[j].greutate < v[i].greutate) { aux = v[i];
                                                          v[i] = v[j];
                                                          v[j] = aux;
                                                          }
         }
     }
}



int main()
{
    FILE *in = NULL, *out = NULL;
    int n, h, u, i, suma = 0, sf_heap = 0, inc_vector = 0, inaltime;
    
// Deschiderea fisierelor    
    in = fopen("gutui.in", "rt");
    out = fopen("gutui.out", "wt");
    if (!in || !out) {printf("Eroare la deschiderea fisierelor"); return -1;}
    
// Citesc datele din fisier si introduc gutuile intr-un vector de perechi (inaltime div u, greutate),
// sortate descrescator dupa inaltime div u, iar in cazul egalitatii dupa greutate
    
    fscanf(in, "%i %i %i",&n, &h, &u);
    
    Gutui gutui[n], aux2;    
    int aux[n];
    
    for (i = 0; i < n; i++)
        {
             fscanf(in, "%i %i", &(gutui[i].inaltime), &(gutui[i].greutate));
             gutui[i].inaltime = (gutui[i].inaltime - 1)/u;
        }
    merge_sort(gutui, 0, n, u);
    
    
// Parcurg tot vectorul culegand mereu prima gutuie gasita cu (inaltimea + nr_gutui_culese * u) < h    
// Daca gasesc gutui neculese mai mari decat minimul dintre cele culese, o culeg pe aceasta in locul minimului

    
    
    inaltime = gutui[0].inaltime;
    for (; inaltime < h/u; inaltime++)
    {
        insert_heap(gutui, inaltime, &sf_heap, &inc_vector, n);
        suma +=gutui[0].greutate;
        for (gutui[0] = gutui[--sf_heap], i = 0; i < sf_heap;)
        {
            if (gutui[2*i+1].greutate < gutui[2*i+2].greutate)
               {
                   aux2 = gutui[2*i+2];
                   gutui[2*i+2] = gutui[i];
                   gutui[i] = aux2;
                   i = 2*i+2;
               }
               else
                   {
                    aux2 = gutui[2*i+1];
                    gutui[2*i+1] = gutui[i];
                    gutui[i] = aux2;
                    i = 2*i+1;
                   }
        }
    }
   
              
    fprintf(out,"%i", suma);
    
    
 fclose(in);
 fclose(out);
 return 0;   
}