Pagini recente » Cod sursa (job #2278334) | Cod sursa (job #1013259) | Cod sursa (job #3216527) | Cod sursa (job #233554) | Cod sursa (job #438591)
Cod sursa(job #438591)
#include <stdio.h>
#include <stdlib.h>
#define FILEIN "gutui.in"
#define FILEOUT "gutui.out"
#define DIM 100002
typedef struct gutuie {
int g, h;
} gutuie;
int min(int a, int b) {
if (a<b) return a;
return b;
}
int insert(int** culegeri[DIM], gutuie gut, int h, int u, int n) {
//puts("intram in insert");
int pozitie_preferata = n, **pozitie_urmatoare = NULL, *val_pozitie_urmatoare = NULL;
/*int i;
printf("Tratam gutuia G=%d, H=%d. La inceput: ", gut.g, gut.h);
for (i=0; i<=n; i++)
if (culegeri[i] == NULL) printf("nul ");
else printf("%d ", *(*(culegeri[i])));
printf("enter\n");*/
//calculam pozitia pe care am vrea sa introducem gutuia
pozitie_preferata = min((h-gut.h)/u, n);
if (culegeri[pozitie_preferata] != NULL) //daca incercam sa introducem gutuia pe o pozitie deja ocupata
pozitie_preferata = *(*(culegeri[pozitie_preferata])); //gasim prima pozitie libera indicata
if (pozitie_preferata < 0) //daca nu am putut determina o pozitie pe care sa introducem gutuia
return 0;
//printf("Prefer pe %d\n", pozitie_preferata);
//in acest moment am gasit pozitia pe care urmeaza sa introducem gutuia
//acum trebuie sa actualizam pozitiile libere indicate de gutuile inconjuratoare
if (pozitie_preferata == n || culegeri[pozitie_preferata+1] == NULL) { //daca nu culegem o gutuie imediat dupa ea
if (pozitie_preferata == 0 || culegeri[pozitie_preferata-1] == NULL) { //daca nu culegem o gutuie imediat inaintea ei
//printf("a\n");
/*pozitie_urmatoare = (int*)malloc(sizeof(int)); //cream un int in care memoram pozitia urmatoare libera
*pozitie_urmatoare = pozitie_preferata - 1; //memoram in acel int pozitia urmatoare libera
//setam pe pozitia aleasa in 'culegeri' sa indice catre un pointer care duce la int-ul cu numarul pozitiei libere
culegeri[pozitie_preferata] = &pozitie_urmatoare;*/
pozitie_urmatoare = (int**)malloc(sizeof(int*)); //cream un int in care memoram pozitia urmatoare libera
*pozitie_urmatoare = val_pozitie_urmatoare = (int*)malloc(sizeof(int)); //memoram in acel int pozitia urmatoare libera
*val_pozitie_urmatoare = pozitie_preferata - 1;
//setam pe pozitia aleasa in 'culegeri' sa indice catre un pointer care duce la int-ul cu numarul pozitiei libere
culegeri[pozitie_preferata] = pozitie_urmatoare;
pozitie_urmatoare = val_pozitie_urmatoare = NULL;
}
else { //daca avem un element in fata noastra
//printf("b\n");
//primul element liber care urmeaza este cel indicat de elementul din fata noastra
culegeri[pozitie_preferata] = culegeri[pozitie_preferata-1];
}
} else { //daca avem un element in spatele nostru
//daca nu avem un element in fata noastra
if (pozitie_preferata == 0 || culegeri[pozitie_preferata-1] == NULL) {
//printf("c\n");
//elementul liber de dupa noi este cel din fata noastra si impartim adresa la care il memoram cu cel din spatele nostru
culegeri[pozitie_preferata] = culegeri[pozitie_preferata+1];
*(*(culegeri[pozitie_preferata])) = *(*(culegeri[pozitie_preferata])) - 1;
}
else { //daca avem un element si in fata noastra (suntem inconjurati)
//printf("d\n");
//elementele din spatele nostru, ca si noi, vor indica la pozitia indicata de elementele din fata noastra
free(*culegeri[pozitie_preferata+1]);
culegeri[pozitie_preferata+1] = culegeri[pozitie_preferata] = culegeri[pozitie_preferata-1];
}
}
/*
printf("La sfarsit: ");
for (i=0; i<=n; i++)
if (culegeri[i] == NULL) printf("nul ");
else printf("%d ", *(*(culegeri[i])));
printf("\n\n");
*/
return 1;
}
int comparator(const void * a, const void * b) {
return -1*(((gutuie*)a)->g - ((gutuie*)b)->g);
}
int main() {
FILE *fin = fopen(FILEIN, "r"), *fout = fopen(FILEOUT, "w");
int n, h, u, i;
long int totalsum = 0; //definim suma totala si intializam cu 0
gutuie gutui[DIM]; //definim vectorul de gutui
int** culegeri[DIM];
//citim datele intr-o lista de gutui
fscanf(fin, "%d %d %d", &n, &h, &u);
for (i=0; i<n; i++) {
fscanf(fin, "%d %d", &gutui[i].h, &gutui[i].g);
culegeri[i] = NULL;
}
culegeri[n] = NULL;
//sfarsit citit date
//sortam datele
qsort(gutui, n, sizeof(gutuie), comparator);
for (i=0; i<n; i++)
//vedem daca putem culege gutuia si ne marcam in vector
if (insert(culegeri, gutui[i], h, u, n))
totalsum += gutui[i].g;
//printf("\nRezultat final: %ld\n", totalsum);
fprintf(fout, "%ld\n", totalsum);
fclose(fin);
fclose(fout);
return 0;
}