Pagini recente » Cod sursa (job #463579) | Cod sursa (job #1437487) | Cod sursa (job #2956506) | Cod sursa (job #463067) | Cod sursa (job #463119)
Cod sursa(job #463119)
/*
* gutui.c
*
* Created on: Apr 4, 2010
* Author: matwix
*/
#include <stdio.h>
#include <stdlib.h>
// Lista dublu inlantuita
typedef struct list_el {
long int inaltime, greutate, nivel;
struct list_el * next, * prev;
} * List;
// Calculez maximul dintr-o lista
List maxim(List *v, long int n){
long int max = 0;
List l, max_l = NULL;
l = v[n];
while (l != NULL){
if (l -> greutate > max){
max = l -> greutate;
max_l = l;
}
l = l -> next;
}
return max_l;
}
// Calculez maximul dintr-un vector de elemente
List max_vect(List *v, long int min, long int max){
long int j, maxi = 0;
List max_l = NULL;
for(j = min; j < max; j++){
if(v[j] != NULL)
if (maxi < v[j] -> greutate){
maxi = v[j] -> greutate;
max_l = v[j];
}
}
return max_l;
}
// Verific daca un vector de liste este gol
int gol(List *v, long int min, long int max){
long int i;
int boo = 0;
for(i = min; i <= max; i++)
if (v[i] != NULL)
boo = 1;
return boo;
}
int main(){
long int n, max = 0, H, U, aux1, aux2, i, nivel_max, nivel_min=2147000000, nivel_curent, j;
List *v_max; // Vector de noduri
FILE *fin = fopen("gutui.in", "r");
FILE *fout = fopen("gutui.out", "w");
List *vector; // Un vector de liste (dictionar) unde indicele este nivelul fructului
List l;
fscanf (fin, "%ld %ld %ld", &n, &H, &U);
nivel_max = H/U;
vector = (List*)malloc((H/U+1)*sizeof(List));
v_max = (List *)malloc((H/U+1)*sizeof(List));
/* Citesc elementele si le adaug in dictionar in functie de nivel*/
for (i = 0; i < n; i++){
fscanf(fin, "%ld %ld", &aux1, &aux2);
l = (List)malloc(sizeof(struct list_el));
l -> inaltime = aux1;
l -> greutate = aux2;
l -> nivel = H/U - (H-aux1)/U;
if(l -> nivel < nivel_min)
nivel_min = l ->nivel;
if (vector[l -> nivel] != NULL){
l -> prev = NULL;
l -> next = vector[l -> nivel];
vector[l -> nivel] -> prev = l;
vector[l -> nivel] = l;
}else{
l -> prev = NULL;
l -> next = NULL;
vector[l -> nivel] = l;
}
}
i = nivel_min;
// Creez un vector de maxime pentru fiecare nivel
for (j = nivel_min; j <= nivel_max; j++){
v_max[j] = maxim(vector, j);
}
while (nivel_max >= i && gol(vector, nivel_min, nivel_max)){
l = max_vect(v_max, nivel_min, i+1); // iau elementul maxim de pe cel mai mic nivel
// Sterg nodul din lista nivelului
if (l != NULL){
nivel_curent = l -> nivel;
max += l -> greutate;
if (l -> prev == NULL){
vector[l -> nivel] = l -> next;
if (l -> next != NULL)
l -> next -> prev = NULL;
free(l);
}else{
if (l -> next == NULL){
l -> prev -> next = NULL;
free(l);
}else{
l -> prev -> next = l -> next;
l -> next -> prev = l -> prev;
free(l);
}
}
// Recalculez maximul de pe nivelul de unde sterg nodul
v_max[nivel_curent] = maxim(vector, nivel_curent);
}
i++; // incrementez nivelul curent
}
fprintf(fout, "%ld", max);
fclose(fin);
fclose(fout);
return 0;
}