Cod sursa(job #437749)

Utilizator adrian.bosilcaBosilca Adrian adrian.bosilca Data 10 aprilie 2010 01:02:41
Problema Gutui Scor 100
Compilator c Status done
Runda teme_upb Marime 2.46 kb
/*
 * File:   Problema2.c
 * Author: Bosilca Adrian 325CC
 *
 */
#include <stdio.h>
#include <stdlib.h>

typedef struct gutuie{      //structura ce contine inaltimea si greutatea unei gutui
    int h;
    int g;
}gutuie;

/**
 * Functie de comparare folosita la sortare.
 * Cu ajutorul acestei functii gutuile sunt sortate descrescator dupa greutate.
 * Daca greutatile sunt egale atunci sunt sortate descrescator dupa inaltime.
 */
int comp(const void* a, const void* b) {
    gutuie *c = (gutuie*)a;
    gutuie *d = (gutuie*)b;
    if ((c->g) == (d->g))
        return (d->h - c->h);
    return ( d->g - c->g );
}

int main() {
    FILE* f = fopen("gutui.in", "r");
    int n, h, u, i, k = 0, s = 0, hh;             //k = nivelul curent de ocupare (toate nivele < k sunt ocupate)
    gutuie v[100000];                             //vector ce contine inaltimea si greutatea fiecarei gutui
    char *niv;                                    //vector ce contine numarul de maxim de nivele pe care se pot gasi gutuile

    fscanf(f, "%d %d %d", &n, &h, &u);            //citirea datelor de intrare
    for (i = 0 ; i < n ; i++)
        fscanf(f, "%d %d", &v[i].h, &v[i].g);
    fclose(f);

    niv = (char*)calloc(h/u+1, sizeof(char));     //aloca spatiu exact cat este nevoie

    qsort(v, n, sizeof(gutuie), comp);            //sorteaza gutuie descrescator dupa greutati(in caz de egalitate -> dupa inaltimi)

    for (i = 0 ; i < n ; i++) {
        hh = (h-v[i].h)/u;                        //nivelul pe care se afla gutuia curenta
        if (hh < k) {                             //daca nivelul gutui curente este ocupat inaltimea acesteia devine h+1
            v[i].h = h+1;
        } else {
            if (hh == k) {                        //fiecare gutuie se pune pe nivelul corespunzator
                niv[k] = 1;
                k++;
            } else {
                while (niv[hh] != 0 && hh > k)    //daca nivelul curent este ocupat si mai pot fi nivele libere dedesubt
                    hh--;
                if (hh >= k)
                    niv[hh] = 1;
            }
        }
        while (niv[k] != 0)                       //se updateaza nivelul curent de ocupare
            k++;
    }

    for (i = 0 ; i < n; i++) {                    //se insumeaza doar gutuile cu inaltimile mai mici decat h (inaltimea maxima la care ajunge Gigel)
        if (v[i].h <= h) {
            s += v[i].g;
        }
    }

    f = fopen("gutui.out", "w");
    fprintf(f, "%d", s);
    fclose(f);

    return 0;
}