Pagini recente » Cod sursa (job #2378787) | Cod sursa (job #819182) | Cod sursa (job #2896855) | Cod sursa (job #2711363) | Cod sursa (job #439242)
Cod sursa(job #439242)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define CHILD(node) ((node) * 2 + 1) //copilul din stanga
typedef struct gutuie {
unsigned int h;
unsigned int g;
} GUTUIE;
typedef GUTUIE (*comp)(const void*,const void*);
int cresc (const void * a, const void * b)
{
if ((*(GUTUIE*)a).h == (*(GUTUIE*)b).h)
return -((*(GUTUIE*)a).g - (*(GUTUIE*)b).g);
return ((*(GUTUIE*)a).h - (*(GUTUIE*)b).h);
}
unsigned int parent(unsigned int i){
if (i % 2 == 0) return (i/2 - 1);
else return i/2;
}
void insert(unsigned int w, unsigned int *heap, unsigned int pos){
heap[pos] = w;
unsigned int aux;
while ((pos > 0) && (heap[pos] < heap[parent(pos)])) {
aux = heap[parent(pos)];
heap[parent(pos)] = heap[pos];
heap[pos] = aux;
pos = parent(pos);
}
}
void minheapify(unsigned int *heap, unsigned int i, unsigned int n){
while ( CHILD(i) < n){
unsigned int child = CHILD(i);
if (child + 1 < n && heap[child] > heap[child+1]) //alegem cel mai mic copil
child++;
if (heap[i] > heap[child]){ //mutam cel mai mic nod in radacina
unsigned int temp = heap[i];
heap[i] = heap[child];
heap[child] = temp;
}
++i;
}
}
int main(){
int N,i;
unsigned int t,H,U,level,sum,no_levels,k,x,min_level;
GUTUIE *g;
FILE *f,*o;
f = fopen("gutui.in","r");
o = fopen("gutui.out","w");
fscanf(f,"%d",&N);
fscanf(f,"%d",&H);
fscanf(f,"%d",&U);
g = malloc(N * sizeof (GUTUIE));
for (i = 0;i < N;i++){
fscanf(f,"%d",&x);
if (H >= x)
g[i].h = (H-x)/U + 1; //cream nivelele in structura
fscanf(f,"%d",&g[i].g);
}
qsort(g, N, sizeof(GUTUIE), cresc);
for ( i = 0;i<N;i++)
printf ("%d %d\n",g[i].h,g[i].g);
min_level = g[0].h;
no_levels = (H - min_level)/U + 1;
unsigned int * heap = (unsigned int *)calloc(no_levels,sizeof(unsigned int));
level = 0; //nr maxim de gutui care poate fi cules de pe un nivel
sum = 0;
k = 0;t = 0; //retinem in k nr de gutui de pe un nivel si in t pozitiile din heap
for (i = 0; i < N; i++){
if (level < g[i].h) {//daca ajungem la un nivel nou
level = g[i].h; //il actualizam
//k = 1; //nr de gutui pe acest nivel
insert(g[i].g, heap, k); //inseram gutuia de pe noul nivel
k++;
sum += g[i].g;
}
else if (level == g[i].h){ //daca intalnim o gutuie pe acelasi nivel
if (k < level){
//daca mai pot fi culese gutui pe acest nivel
insert(g[i].g, heap, k); //inseram o gutuie in heap pe pozitia k
k++;
sum += g[i].g; // si adunam la suma
}
else { //daca am atins in heap nr maxim de gutui pentru un nivel
if (heap[0] < g[i].g) { //daca minimul din heap e mai mic decat greutatea gutuii actuale
sum = sum - heap[0] + g[i].g; //actualizam suma
heap[0] = g[i].g; //inseram in radacina si apoi coboram
minheapify(heap, 0, k);
}
}
}
}
fprintf(o,"%d\n",sum);
fclose(f);
fclose(o);
return 0;
}