Pagini recente » Cod sursa (job #304193) | Cod sursa (job #2981293) | Cod sursa (job #981681) | Cod sursa (job #437115) | Cod sursa (job #435646)
Cod sursa(job #435646)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define FILEIN "gutui.in"
#define FILEOUT "gutui.out"
#define INFINIT 4294967295
#define DISPLAY 0
typedef struct gutuie {
int g, h;
gutuie *next;
} gutuie;
typedef struct elem {
unsigned int val;
elem *next;
} elem;
int insert(elem *start, gutuie *gutui, int h, int u) {
unsigned int nivel_maxim_gutuie = (h-gutui->h)/u;
int out_of_bounds = 0;
//if (DISPLAY) { printf("Gutuia noua poate fi pusa la cel mult %ud.\n", nivel_maxim_gutuie); fflush(stdout); }
elem *p = start->next, *previous = start, *nou;
//parcurgem de la final toate gutuile puse pana atunci
while (p) {
//if (DISPLAY) { printf("Suntem la gutuia de nivel %ud. Nivelul maxim curent e %ud. ", p->val, nivel_maxim_gutuie); fflush(stdout); }
//daca gutuia curenta poate fi pusa mai tarziu decat gutuia noua
if (p->val >= nivel_maxim_gutuie) {
//if (DISPLAY) { printf("Trecem la urmatoarea\n"); fflush(stdout); }
//trecem la urmatoarea gutuie
if (p->val == nivel_maxim_gutuie) {
if (nivel_maxim_gutuie)
nivel_maxim_gutuie--;
else
out_of_bounds = 1;
}
previous = p;
p = p->next;
}
//daca am ajuns la punctul la care am putea sa adaugam, verificam daca se poate
else {
//if (DISPLAY) { printf("\nIncercam sa adaugam gutuia in lista (intre nivelele %ud si %ud)... ", previous->val, p->val); fflush(stdout); }
//daca o putem adauga
if ((previous->val - nivel_maxim_gutuie) && (nivel_maxim_gutuie - p->val) && nivel_maxim_gutuie >= 0) {
//if (DISPLAY) { printf("OK\n"); fflush(stdout); }
//adaugam noua gutuie intre previous si p
nou = (elem*)malloc(sizeof(elem));
nou->val = nivel_maxim_gutuie;
nou->next = p;
previous->next = nou;
return 1;
}
//daca nu se poate adauga
else {
//if (DISPLAY) { printf("Nu\n"); fflush(stdout); }
return 0;
}
} //end verificare si adaugare
}//end while
//daca am ajuns pana aici inseamna ca ar trebui sa incercam la inceputul listei
//if (DISPLAY) { printf("Incercam sa adaugam gutuia la inceputul listei (cu nivel %d), inaintea gutuii de nivel %ud ... ", nivel_maxim_gutuie, previous->val); fflush(stdout); }
if ((previous->val - nivel_maxim_gutuie) && !out_of_bounds) {
//if (DISPLAY) { printf("Okay\n"); fflush(stdout); }
nou = (elem*)malloc(sizeof(elem));
nou->val = nivel_maxim_gutuie;
nou->next = previous->next;
previous->next = nou;
return 1;
}
//if (DISPLAY) { printf("Nu\n"); fflush(stdout); }
return 0;
}
int main() {
FILE *fin = fopen(FILEIN, "r"), *fout = fopen(FILEOUT, "w");
int n, h, u, i;
long int totalsum = 0;
gutuie *gutui, *nou, *p, *prev, *gutuiend;
elem *start;
//citim datele intr-o lista de gutui
fscanf(fin, "%d %d %d", &n, &h, &u);
gutui = (gutuie*)malloc(sizeof(gutuie));
fscanf(fin, "%d %d", &gutui->h, &gutui->g);
gutui->next = NULL;
gutuiend = gutui;
for (i=2; i<=n; i++) {
nou = (gutuie*)malloc(sizeof(gutuie));
fscanf(fin, "%d %d", &nou->h, &nou->g);
p = gutui;
//daca trebuie pusa in capul listei
if (p->g <= nou->g) {
nou->next = p;
gutui = nou;
continue;
}
//daca trebuie pusa la sfarsitul listei
if (gutuiend->g >= nou->g) {
if (!gutuiend->next) {
gutuiend->next = nou;
nou->next = NULL;
gutuiend = nou;
continue;
} else p = gutuiend;
}
//daca am ajuns aici atunci sigur nu trebuie pusa in capul listei
prev = p;
p = p->next;
while (p && p->g > nou->g) {
prev = p;
p = p->next;
}
prev->next = nou;
nou->next = p;
gutuiend = nou;
}
//sfarsit citit date
//if (DISPLAY) {printf("Am citit toate datele\n\n"); fflush(stdout);}
//initializam lista de gutui care le culegem
start = (elem*)malloc(sizeof(elem));
start->val = INFINIT;
start->next = NULL;
//luam gutuile in ordinea descrescatoare a greutatii
p = gutui;
for (i=1; i<=n; i++) {
//if (DISPLAY) { printf("Incerc sa adaug (%d, %d) la lant. ", p->g, p->h); fflush(stdout); }
//vedem daca putem pune gutuia maxima in lista
if (insert(start, p, h, u)) {
//if (DISPLAY) { printf("Am adaugat gutuia\n"); fflush(stdout); }
totalsum += p->g;
}
//else if (DISPLAY) { printf("Nu am adaugat gutuia\n"); fflush(stdout); }
//if (DISPLAY) printf("Suma partiala %ld\n", totalsum);
p = p->next;
}
//if (DISPLAY) printf("Suma maxima finala: %ld\n", totalsum);
fprintf(fout, "%ld\n", totalsum);
fclose(fin);
fclose(fout);
return 0;
}