Pagini recente » Cod sursa (job #1516149) | Cod sursa (job #2245408) | Cod sursa (job #1191002) | Cod sursa (job #3155107) | Cod sursa (job #435479)
Cod sursa(job #435479)
/*
======================== TEMA 1 PA =========================
===Problema 2 - Gutui===
Student : PALITA FLORIAN
GRUPA : 324 CC
=============================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structura care retine pentru o gutuie inaltimea si greutatea
typedef struct gutui {
int inaltime;
int greutate;
} gutui;
//Structura unui nivel din copac
typedef struct niv {
int greutati[10000];
int lung;
} niv;
int N; //Numarul de gutui
int H; //Inaltimea maxima la care ajunge
int U; //Inaltimea cu care se ridica
FILE *g; //Fisier de iesire
gutui p[100000]; //Vector cu cele N perechi inaltime - greutate
niv nivele[10000]; //Vector cu nivelele gutuiului
int numar_nivele = 0; //Numarul de nivele
int g_gutui[100000]; //Vector cu greutatile gutuilor
int marcaje[100000]; //Vector cu marcaje ( 1-daca gutuia e pe nivelul actual , 0-daca nu )
int n_gutui[100000]; //Vector cu nivelul pe care e gutuia
//Functia de comparare pentru qsort
int compare (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
//Functie pentru preluarea datelor din fisierul de intrare
void input_data() {
FILE *f;
int i, j = 0;
f = fopen("gutui.in", "r");
fscanf(f, "%d %d %d\n", &N, &H, &U);
for (i = 0 ; i < N ; i++) {
fscanf(f, "%d %d\n", &p[i].inaltime, &p[i].greutate);
marcaje[i] = 0;
g_gutui[j] = p[i].greutate;
j++;
}
fclose(f);
}
//Functie ce partitioneaza pe nivele gutuile
void partition() {
int inf, sup, i;
sup = H;
inf = H - U;
while (inf > 0) {
nivele[numar_nivele].lung = 0;
for (i = 0 ; i < N ; i++)
if ((p[i].inaltime > inf) && (p[i].inaltime <= sup)) {
nivele[numar_nivele].greutati[nivele[numar_nivele].lung] = g_gutui[i];
n_gutui[i] = numar_nivele;
nivele[numar_nivele].lung++;
}
numar_nivele++;
sup = inf;
inf = inf - U;
}
if (inf == 0) {
nivele[numar_nivele].lung = 0;
for (i = 0 ; i < N ; i++)
if ((p[i].inaltime > inf) && (p[i].inaltime <= sup)) {
nivele[numar_nivele].greutati[nivele[numar_nivele].lung] = g_gutui[i];
n_gutui[i] = numar_nivele;
nivele[numar_nivele].lung++;
}
numar_nivele++;
}
if (inf < 0) {
nivele[numar_nivele].lung = 0;
for (i = 0 ; i < N ; i++)
if ((p[i].inaltime >= 0) && (p[i].inaltime <= sup)) {
nivele[numar_nivele].greutati[nivele[numar_nivele].lung] = g_gutui[i];
n_gutui[i] = numar_nivele;
nivele[numar_nivele].lung++;
}
numar_nivele++;
}
}
//Functie ce calculeaza maximul greutatii de pe nivelul maxim
int maxim_nivel() {
int i, max = 0, j;
if (nivele[0].lung == 0)
return 0;
for (i = 0 ; i < nivele[0].lung ; i++)
if (nivele[0].greutati[i] > max)
for (j = 0 ; j < N ; j++)
if ((g_gutui[j] == nivele[0].greutati[i]) && (marcaje[j] == 0) && (n_gutui[j] == 0))
max = nivele[0].greutati[i];
return max;
}
//Functie care sterge primul nivel , dupa culegerea unei gutui
void stergeNivel() {
int i, j;
for (i = 1 ; i < numar_nivele ; i++) {
nivele[i-1].lung = nivele[i].lung;
for (j = 0 ; j < nivele[i-1].lung ; j++)
nivele[i-1].greutati[j] = nivele[i].greutati[j];
}
numar_nivele--;
for (i = 0 ; i < N ; i++)
n_gutui[i]--;
}
int main() {
int max, i, j, G = 0, u = 100, temp, ok;
int g_gutui2[100000],ordine[100000];
input_data();
partition();
while ((numar_nivele > 0) && ( u != 0)) {
//Preiau maximul de pe nivelul cel mai de sus
max = maxim_nivel();
//Marchez gutuile de pe nivel cu 1 pentru ca nu mai pot fi culese
for (i = 0 ; i < N ; i++)
if (n_gutui[i] == 0)
marcaje[i] = 1;
u = 0;
//Creez vectorul gutui2 cu greutatile care mai pot fi culese
for (i = 0 ; i < N ; i++)
if (marcaje[i] == 0) {
ordine[u] = i;
g_gutui2[u] = g_gutui[i];
u++;
}
//Sortez vectorul gutui2 crescator si sortez si ordinea lor
//qsort(g_gutui2, u, sizeof(int), compare);
for (i = 0 ; i < u - 1 ; i++)
for (j = i + 1 ; j < u ; j++)
if (g_gutui2[i] > g_gutui2[j]) {
temp = g_gutui2[i];
g_gutui2[i] = g_gutui2[j];
g_gutui2[j] = temp;
temp = ordine[i];
ordine[i] = ordine[j];
ordine[j] = temp;
}
else
if ((g_gutui2[i] == g_gutui2[j]) && (n_gutui[ordine[i]] < n_gutui[ordine[j]])) {
temp = g_gutui2[i];
g_gutui2[i] = g_gutui2[j];
g_gutui2[j] = temp;
temp = ordine[i];
ordine[i] = ordine[j];
ordine[j] = temp;
}
ok = 0;
//Caut al doilea maxim
for (i = u - 2 ; i >= 0 ; i--)
if (g_gutui2[i] < g_gutui2[u-1]) {
ok = 1;
break;
}
if (max == 0) {
//Daca nivelul maxim nu are gutui , iau maximul din ce a mai ramas , si bifez
G += g_gutui2[u-1];
marcaje[ordine[u-1]] = 1;
}
else
if (u == 1 || ok == 0) {
//Daca pe nivelul maxim am cel putin o gutuie , si in restul copacului mai e doar una , o culeg pe aceasta de sus
G += max;
}
else
//Daca sunt mai multe gutui in restul copacului si gutuia de pe nivelul maxim e mai grea decat al doilea maxim din rest o culeg
if (max >= g_gutui2[i]) {
G += max;
}
else {
G += g_gutui2[u-1];
marcaje[ordine[u-1]] = 1;
}
u = 0;
for (i = 0 ; i < N ; i++)
if (marcaje[i] == 0)
u++;
stergeNivel();
}
g = fopen("gutui.out", "w");
fprintf(g, "%d\n", G);
fclose(g);
return 0;
}