Cod sursa(job #439833)

Utilizator ShmazZamfirache Virgil Shmaz Data 11 aprilie 2010 19:42:10
Problema Gutui Scor 100
Compilator cpp Status done
Runda teme_upb Marime 3.44 kb
/* Zamfirache Virgil - 323CC
 * PA - TEMA 1 - PROBLEMA 2*/

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <queue>

using namespace std;

//Structura pentru o gutuie 
typedef struct gutuie { 
		int level;    // Nivelul unei gutui ( H - height[ i ] / U ) 
        int weight;   // Greutatea unei gutui  
}gutuie;

//Functie comparare pentru qSort (sortare descrescatoare fata de inaltime ) ( crescatoare pe nivele pornind de la cel maxim )
int compare(const void* a,const void* b)
{	
    return  ( ( ( const gutuie * ) a) -> level - ( ( const gutuie * ) b ) -> level);

}

//Functie pentru alegerea gutuilor ce dau profit maxim
void profit_gutui( gutuie *gutui, int N, int H, int U)
{   
	FILE *out ;

    out =  fopen ( "gutui.out", "w" );
    
    int i , w_max = 0;    
    
	//Sortam vectorul de structuri gutui, in functie de greutatea gutuilor, descrescator
	qsort((void *) gutui,               // Adresa de inceput al vectorului de structuri
        N,                              // Numarul de gutui
        sizeof( gutuie ),               // Dimensiunea structurii gutuie
        compare );                      // Pointer la functia de comparare de structuri "gutui"
		
	// Structura auxiliara in care vom adauga gutuile si un iterator pentru ea		
	//multimap<int,int> aux;
	//multimap<int,int>::iterator it;
	
	priority_queue<unsigned int, std::vector<unsigned int>, std::greater<unsigned int> > aux;

	
	
	
	int lvl = 0 ;
	
	// Parcurgem toate gutuile (sortate descrescator in functie de inaltime )
	for ( i = 0 ; i < N ; i ++ ) {
		
		if ( lvl <= gutui[ i ].level ) {
		   
		   //aux.insert( pair <int, int > ( gutui[ i ].weight, gutui[ i ].level ) );
           aux.push( gutui[ i ].weight) ;
		   lvl++;  
		   w_max += gutui[ i ].weight; 
		   continue;	 
	    
		}
		
		if ( lvl > gutui[ i ].level ){
	    
		    //it = aux.begin();
		    if ( gutui[ i ].weight > aux.top() ) {
	   	        w_max = w_max - aux.top() + gutui [ i ].weight ;
	   	        aux.pop();
	   	        aux.push( gutui[ i ].weight ); 
			    //aux.erase( it );
			    //aux.insert( pair <int, int > ( gutui[ i ].weight, gutui[ i ].level ) );  
				continue;
	        } 	 
		}
	}

	// Scriere rezultat in fisierul de iesire
	fprintf ( out , "%d", w_max);
    fclose ( out ) ;
		
}

//Functie de citire din fisier in vectorul de structuri gutui
void read( char *fname , gutuie **gutui, int *N, int *H, int *U )
{
    FILE *in ;
    int i;
    in =  fopen ( fname, "r" );
    int haux;
    
    fscanf(in, "%d", N);
    fscanf(in, "%d", H);
    fscanf(in, "%d", U);
	
	//Aloca vectorul de structuri gutui si citeste din fisier
	*gutui = ( gutuie * )calloc( ( * N ), sizeof( gutuie));

	for ( i = 0; i < *N ; i++) {
			
			// Citire inaltime gutuie: i  si salvarea nivelului gutuii relativ la inaltimea maxima  ( H )
			fscanf ( in, "%d", &haux );
			( *gutui)[ i ].level = ( *H - haux )/ *U;

            // Citire greutate gutuie: i 
			fscanf ( in, "%d", & ( ( *gutui)[ i ].weight ));

	}

	fclose ( in );
}

int main()
{
    gutuie *gutui;
    
    /*
	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).*/
	
    int N, H, U ;
    char in_name[ ] = "gutui.in";
	
	read( in_name, &gutui , &N, &H, &U );
	
    profit_gutui( gutui, N, H, U);

    return 0;
}