Cod sursa(job #463579)

Utilizator simona.poilincaSimona Poilinca simona.poilinca Data 16 iunie 2010 14:33:43
Problema Gutui Scor 100
Compilator c Status done
Runda teme_upb Marime 4.14 kb
//Tema 1 PA
//Surdu Cristina 321CA

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int **mat; //matricea principala, de gutui; o declar ca variabila globala deoarece o folosesc in mai multe functii


//sortez gutuile dupa greutate; folosesc quicksort;
//mi-am facut o matrice care sa retina pe prima coloana inaltimea si pe a doua greutatea; cand sortez dupa greutate, trebuie sa-mi mut si inaltimea pe pozitia care trebuie; de aceea se fac 2 interschimburi in functia partition

//functia de partitionare
int partition (int left, int right, int pivotIndex) 
{
	int pivotValue = mat[pivotIndex][1];
	int aux, i;
	aux = mat[pivotIndex][1];
	mat[pivotIndex][1] = mat[right][1];
	mat[right][1] = aux; 
	
	aux = mat[pivotIndex][0];
	mat[pivotIndex][0] = mat[right][0];
	mat[right][0] = aux;
	

	int storeIndex = left;
   	for (i = left; i < right; i++) 
        if (mat[i][1] > pivotValue)  
	{
           	aux = mat[i][1];
		mat[i][1] = mat[storeIndex][1];
		mat[storeIndex][1] = aux;
			
		aux = mat[i][0];
		mat[i][0] = mat[storeIndex][0];
		mat[storeIndex][0] = aux;

            	storeIndex++;
	}
	aux = mat[storeIndex][1];
	mat[storeIndex][1] = mat[right][1];
	mat[right][1] = aux; 
	
	aux = mat[storeIndex][0];
	mat[storeIndex][0] = mat[right][0];
	mat[right][0] = aux;
	
return storeIndex;
}

//sortarea	
void quicksort(int left, int right) 
{
	if (right > left) 
	{
         	int pivotIndex = (left+right)/2;
         	int pivotNewIndex = partition(left, right, pivotIndex);
         	quicksort(left, pivotNewIndex);
         	quicksort(pivotNewIndex + 1, right);
	}
}

int main ()
{
	FILE *fin = fopen ("gutui.in", "r");
	FILE *fout = fopen ("gutui.out", "w");
	int N, H, U;
	int greutate = 0; //greutatea totala pe care o poate cara Gigel
	int i, j;
	int aux, max=0;
	
	fscanf (fin, "%d%d%d", &N, &H, &U);
	
	//se aloca memorie
	mat = (int**) malloc (N*sizeof (int*));
	for (i=0; i<N; i++)
		mat[i]=(int*) malloc (2*sizeof(int));
	
	for (i=0; i<N; i++)
		for (j=0; j<2; j++)
			fscanf (fin, "%d", &mat[i][j]);
	
	//caz de baza, cand h[i] > H, adica nu poate sa ia nici o gutuie	
	for (i=0; i<N; i++)		
		if (mat[i][0] > H)
		{
			greutate = 0;
			break;
		}
			
	
	//sortez matricea mat[][] in functie de greutate
	quicksort (0, N-1);
		
	
	//max este numarul maxim de ridicari permise; daca am ultima gutuie la nivelul 47 si U=10, atunci max=5
	for (i=0; i<N; i++)
	{
		aux = H-mat[i][0];
		if (aux<0)
			continue;
		aux /= U;
		if (aux > max)
			max = aux;
	}
		
	int marime = max + 1; //numarul maxim de gutui pe care le-as putea culege, daca as avea pe fiecare nivel cate o gutuie

	int *gutui_de_adunat, se_poate=1;
	
	//gutui_de_adunat este un vector in care imi pun greutatile gutuilor pe care le poate lua Gigel, astfel incat sa ia o greutate totala maxima
	gutui_de_adunat = (int *) calloc (marime, sizeof (int));
	
	j=0; 
	int nr_gutui=0;
	while (nr_gutui <= max && j < N)
	{
		i = H - mat[j][0];
		if (i<0) //daca e negativ, continui, ca se poate sa dea un rezultat gresit la impartirea numerelor negative
		{
			j++;
			continue;
		}
		
		i /= U; 
		
		se_poate=1;

		//in vectorul gutui_de_adunat pun pe pozitia i (adica etapa in care se afla gutuia respectiva) greutatea; se poate ca 2 gutui sa se afle la aceeasi inaltime; Gigel o sa ia prima data gutuia mai grea; daca a doua oara poate s-o ia pe a doua, nu mai poate s-o puna tot pe pozitia i (care i s-ar cuveni); trebuie sa se duca la o etapa mai mica (i-- pana cand gaseste un loc liber in vector)
		while (gutui_de_adunat[i])
		{
			i--;
			if (i < 0) 
			{
				se_poate=0;	
				break;
			}
		}
		if (se_poate)
		{
			gutui_de_adunat[i] = mat[j][1];
			nr_gutui++;
		}
		j++;	
	}
	//la final, o sa fie format vectorul cu greutatile gutuilor bune culese de Gigel
	

	//adun la greutate fiecare element din vectorul gutui_de_adunat si rezultatul e ceea ce culege Gigel
	for (i=0; i<marime; i++)
		greutate += gutui_de_adunat[i];

	fprintf (fout, "%d\n", greutate);
	
	
	//se inchid fisierele
	fclose (fin);
	fclose (fout);

	//se elibereaza memoria
	free (mat);
	free (gutui_de_adunat);

	
return 0;
}