Pagini recente » Cod sursa (job #534248) | Cod sursa (job #2867928) | Cod sursa (job #1483049) | Cod sursa (job #1254385) | Cod sursa (job #436892)
Cod sursa(job #436892)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define DEBUG
#define INITIAL_ALLOCED 10
#define INDEX(h) ((H - (h))/U) // nivelul in care intra o anumita gutaie in functie de inaltime
#define LEVELS ((H/U) + 1) // numarul de nivele in functie de intalimea maxima si diferenta dintre
// nivele
#define swap(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
typedef struct _gt // descrie o gutuie prin g (greutate) si h (inaltime)
{
uint32_t g;
uint32_t h;
} Gut, *PGut;
typedef struct _level // descrie un nivel -- o sectiune care cuprinde gutuile intre o inaltime h si h + U
// (unde h - 1 este divizibil cu U)
{
uint32_t size; // numarul de gutui din nivelul curent
uint32_t alloced; // numarul de PGut alocate
int32_t current_primary_max; // index-ul din entries cu gutuia cu greutatea cea mai mare (sau -1)
int32_t current_secondary_max; // index-ul din entries cu gutuia cu a doua greutate (sau -1)
PGut* entries; // size intrari de tipul PGut care descriu gutuile din nivelul curent
} Level, *PLevel;
int N, H, U; // Numarul de Gutui, Inaltimea maxima, Pasul de inaltare
PLevel level_new(); // Aloca memorie pentru un nou nivel
void level_append(PLevel, PGut); // Adauga o intrare de tip PGut intr-un nivel
uint32_t level_get_primary_max_g(PLevel); // Returneaza greutatea maxima dintr-un nivel
uint32_t level_get_secondary_max_g(PLevel); // Returneaza a doua greutate dintr-un nivel
uint32_t level_remove_primary_max(PLevel); // Sterge elementul cu cea mai mare greutate (si o returneaza)
uint32_t level_remove_secondary_max(PLevel); // Sterge elementul cu a doua greutate (si o returneaza)
void level_sort(PLevel); // Sorteza intrarile dintr-un anumit nivel dupa greutate
int main()
{
freopen("gutui.in", "r", stdin);
freopen("gutui.out", "w", stdout);
int i, j;
scanf("%d%d%d", &N, &H, &U);
PLevel* levels = (PLevel*)calloc(LEVELS, sizeof(PLevel));
for(i = 0; i < LEVELS; i ++)
levels[i] = level_new();
for(i = 0; i < N; i ++)
{
PGut gut = (PGut)malloc(sizeof(Gut));
scanf("%d%d", &gut->h, &gut->g);
level_append(levels[INDEX(gut->h)], gut);
}
for(i = 0; i < LEVELS; i ++)
level_sort(levels[i]);
#ifdef DEBUG
for(i = 0; i < LEVELS; i ++)
{
printf("Nivelul %d\n", i);
for(j = 0; j < levels[i]->size; j ++)
printf("(%d %d) ", levels[i]->entries[j]->g, levels[i]->entries[j]->h);
printf("\n\n");
}
#endif
return 0;
}
PLevel level_new()
{
PLevel level = (PLevel)malloc(sizeof(Level));
level->size = 0;
level->alloced = INITIAL_ALLOCED;
level->current_primary_max = -1;
level->current_secondary_max = -1;
level->entries = (PGut*)malloc(INITIAL_ALLOCED * sizeof(PGut));
level->entries[0] = NULL;
return level;
}
void level_append(PLevel lvl, PGut gut)
{
if(lvl->size == lvl->alloced - 1)
{
lvl->alloced *= 2;
lvl->entries = (PGut*)realloc(lvl->entries, lvl->alloced * sizeof(PGut));
}
lvl->entries[lvl->size ++] = gut;
lvl->entries[lvl->size] = NULL;
}
uint32_t level_get_primary_max_g(PLevel lvl)
{
if(lvl->current_primary_max == -1)
return 0;
else
return lvl->entries[lvl->current_primary_max]->g;
}
uint32_t level_get_secondary_max_g(PLevel lvl)
{
if(lvl->current_secondary_max == -1)
return 0;
else
return lvl->entries[lvl->current_secondary_max]->g;
}
uint32_t level_remove_primary_max(PLevel lvl)
{
if(lvl->current_primary_max == -1)
return 0;
uint32_t ret = lvl->entries[lvl->current_primary_max]->g;
lvl->current_primary_max = lvl->current_secondary_max;
lvl->current_secondary_max ++;
if(lvl->current_secondary_max == 0 || lvl->entries[lvl->current_secondary_max] == NULL)
lvl->current_secondary_max = -1;
return ret;
}
uint32_t level_remove_secondary_max(PLevel lvl)
{
if(lvl->current_secondary_max == -1)
return 0;
uint32_t ret = lvl->entries[lvl->current_secondary_max]->g;
lvl->current_secondary_max ++;
if(lvl->entries[lvl->current_secondary_max] == NULL)
lvl->current_secondary_max = -1;
return ret;
}
int comp_gut(const void* gut1, const void* gut2)
{
return (*(PGut*)gut2)->g - (*(PGut*)gut1)->g;
}
void level_sort(PLevel lvl)
{
qsort(lvl->entries, lvl->size, sizeof(PGut), comp_gut);
// if(lvl->entries[0] != NULL)
/*int levels = LEVELS;
int size = lvl->size;
int i;
while(-- levels && size)
{
for(i = 0; i < size - 1; i ++)
if(lvl->entries[i]->g > lvl->entries[i + 1]->g)
{
swap(lvl->entries[i]->g, lvl->entries[i + 1]->g);
swap(lvl->entries[i]->h, lvl->entries[i + 1]->h);
}
size --;
}*/
}