Cod sursa(job #441722)

Utilizator tatiana.cristeacristea tatiana.cristea Data 13 aprilie 2010 11:04:10
Problema Gutui Scor 10
Compilator c Status done
Runda teme_upb Marime 5.19 kb
/*
Gigel are in curte un gutui. El se hotaraste sa culeaga cat mai multe gutui, dar are o problema: copacul este atat de incarcat 
* cu fructe incat la fiecare gutuie culeasa, toate crengile acestuia se ridica in inaltime cu fix U centimetrii. Din pacate Gigel 
* nu are scara la el si nu poate sa culeaga gutui la o inaltime mai mare de H centimetrii.

Nici de aceasta data Gigel nu se descurca singur. Ajutati-l sa culeaga cat mai multe gutui.

Stiind greutatea si inaltimea initiala a fiecarui fruct, se cere cea mai mare recolta de gutui pe care o poate aduce Gigel acasa.
*  Cum se gandeste sa le vanda in piata, il intereseaza o greutate cat mai mare, nu un numar cat mai mare.

Date de intrare
Pe prima linie a fisierului de intrare gutui.in se afla 3 numere intregi: N (numarul de gutui din copac), H (inaltimea maxima la 
* care ajunge Gigel) si U (cu cat se ridica crengile copacului dupa culegerea unei gutui).
Pe urmatoarele N linii se afla cate 2 numere intregi reprezentand inaltimiile si greutatile gutuilor din copac.

Date de ieşire
In fisierul de iesire gutui.out trebuie scrisa greutatea maxima a gutuilor pe care le poate culege Gigel.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

//structura ce caracterizeaza un gutui

struct gutui
{
	long int inaltime;
	long int greutate;
	
};
typedef struct gutui Gutui;

//structura cu gutui si prioritate pe care o are in anumite circumstante

struct date
{
	Gutui fruct; 		
	long int priority;	
};
typedef struct date date_t;

struct heap 
{        long n;//nr de elem
         date_t * a;//un vector a
};
typedef struct heap* HB;
//nu am folosit librarii ca sa pot sort dar am luat algoritmul de pe net

void quicksort(date_t * arr, long int low, long int high) {
 long int i = low;
 long int j = high;
 date_t y ;
 /* compare value */
 date_t z = arr[(low + high) / 2];

 /* partition */
 do {
  /* find member above ... */
  while(arr[i].priority > z.priority) i++;

  /* find element below ... */
  while(arr[j].priority < z.priority) j--;

  if(i <= j) {
   /* swap two elements */
   y = arr[i];
   arr[i] = arr[j]; 
   arr[j] = y;
   i++; 
   j--;
  }
 } while(i <= j);

 /* recurse */
 if(low < j) 
  quicksort(arr, low, j);

 if(i < high) 
  quicksort(arr, i, high); 
}
//Constructorul cozii de tip Heap
HB NewHeap(int maxim)
{
   HB h=(HB)malloc(sizeof(struct heap));
   h->n=0;
   h->a=(date_t*)malloc(maxim*sizeof(struct date_t*));
   return h;
}

//Verifica daca coada este goala sau nu
int EmptyHB(HB h)
{
   return h->n==0;
}
 date_t get_min(HB h)
 {
	return h->a[0];
}

//Sterge elementul cu costul cel mai mic din coada prioritara si il intoarce
void Replace(HB h,date_t x)
{
  assert(!EmptyHB(h));
  date_t aux=h->a[0];
  h->a[0]=x;
  //h->n--;
  }

//Insereaza element in heap
void InsertHB(HB h,date_t x0)
{
  h->n++;
  int n=h->n;
  h->a[n-1]=x0;
}

//Reconstruieste structura de tip Heap, in functie de formula de cost
void rebuildHeap(date_t *a, int heapDim, int i) 
{
   int left, right, max; 
   date_t temp;
   left = 2*i+1;
   right = 2*i+2 ;
   if ((left<heapDim) && (a[left].priority<a[i].priority)) max = left;
   else max = i;
   if ((right<heapDim) && (a[right].priority<a[max].priority)) max = right;
   if (max!=i) 
     {
         temp = a[i];a[i] = a[max];a[max] = temp;
         rebuildHeap(a, heapDim, max);
      }
}

//Construieste un heap
void buildHeap(HB h) 
{
  int i;
  for(i=h->n/2-1; i>=0; i--)
         rebuildHeap(h->a,h->n, i);
}


int det_min(date_t *vec,long int n)
{
	long int i,j=0,min=vec[0].priority;
	for(i=0;i<n;i++)
		if(min>vec[i].priority)
			{
				min=vec[i].priority;
				j=i;
			}
	return j;
}

int main()
{
	FILE *pf_int,*pf_ies;
	long int j=0,n_cules=0,i = 0 , N = 0 , kg=0, H = 0 , U = 0 ;
	date_t *copac,data;//copac=toate gutuiele din copac, cules= gutuile culese de Gigel
	pf_int = fopen("gutui.in","r");
	HB cules;
	pf_ies = fopen("gutui.out","w");
	fscanf(pf_int,"%ld %ld %ld",&N,&H,&U);
	copac=(date_t*)malloc((N+1)*sizeof(date_t));
	
	//citesc toate fructele
	for( i = 0; i < N ; i++ )
	{
		fscanf(pf_int,"%ld %ld",&copac[i].fruct.inaltime,&copac[i].fruct.greutate);
		copac[i].priority=copac[i].fruct.inaltime;//prioritatea cu care sunt in copac e inaltimea
	}
	//le sortez descrescator in functie de inaltime
	quicksort(copac,0,N-1);
	i=0;
	cules=NewHeap(N);
	//cat timp nu am parcurs toate gutuiele din copac
	while(i<N)
	{
		if(cules->n*U+copac[i].fruct.inaltime<=H)//vad daca e o gutuie pe care pot sa o ajung la momentul respectiv
			{
				//daca da o culeg
				data.fruct=copac[i].fruct;
				data.priority=copac[i].fruct.greutate;
				InsertHB(cules,data);
				rebuildHeap(cules->a,cules->n,0);
			}
		else
			{
				//daca nu atunci verific daca gutuia cea mai usoara din cele culese nu e mai usoara si decat gutuia curenta 
				//daca da, atunci le interschimb
				data=get_min(cules);
				if(data.priority<copac[i].fruct.greutate)
				{
					data.priority=copac[i].fruct.greutate;//priotatea cu care le pun in cos greutatea
					data.fruct=copac[i].fruct;
					Replace(cules,data);
					rebuildHeap(cules->a,cules->n,0);
				}
			}
		i++;
	}
	//determin greutatea maxima
	for(i = 0 ; i<cules->n; i++ )
	{
		kg+=cules->a[i].priority;
	}
	fprintf(pf_ies,"%ld\n",kg);
	fclose(pf_int);
	fclose(pf_ies);
	return 0;
}