Cod sursa(job #435368)

Utilizator radu.comanRadu Coman - UPB radu.coman Data 7 aprilie 2010 12:50:11
Problema Gutui Scor 100
Compilator c Status done
Runda teme_upb Marime 2.9 kb
#include <stdio.h>
#include <stdlib.h>

typedef struct{
        int inaltime, greutate;
        } Gutui;



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/u > v[j].inaltime/u) v[contor++] = aux[i++];
        else
            if (v[j].inaltime/u > aux[i].inaltime/u) 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;
}


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;}
         
}


int main()
{
    FILE *in = NULL, *out = NULL;
    int n, h, u, i, j, nr = 0, suma = 0, min = 2147483647, min_ind;
    
// 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 , greutate),
// sortate descrescator dupa inaltime div u, iar in cazul egalitatii dupa greutate
    
    fscanf(in, "%i %i %i",&n, &h, &u);
    
    Gutui gutui[n];    
    int aux[n];
    
    for (i = 0; i < n; i++)
        fscanf(in, "%i %i", &(gutui[i].inaltime), &(gutui[i].greutate));
    
    merge_sort(gutui, 0, n, u);
    
    
// Parcurg tot vectorul culegand mereu prima gutuie gasita cu (inaltimea + nr_gutui_culese * u) < h    
    for (i = 0, j = 0; i < n; i++)
        if ( gutui[i].inaltime + nr <= h) 
           {
             nr += u;
             suma += gutui[i].greutate;
             if (min > gutui[i].greutate) {min = gutui[i].greutate; min_ind = j;}
             aux[j++] = gutui[i].greutate; 
           }
           else
               if (gutui[i].greutate > min && j) 
                  { suma = suma - min + gutui[i].greutate;
                    aux[min_ind] = gutui[i].greutate; 
                    min = gutui[i].greutate; 
                    search_min(aux, &min_ind, &min, j);
                  }
              
    fprintf(out,"%i", suma);
    
    
 fclose(in);
 fclose(out);
 return 0;   
}