Cod sursa(job #439900)

Utilizator thoradinMarius Latu thoradin Data 11 aprilie 2010 20:18:27
Problema Gutui Scor 20
Compilator c Status done
Runda teme_upb Marime 4.4 kb
#include <stdio.h>
#include <stdlib.h>

#define infile "gutui.in"
#define outfile "gutui.out"

int NMAX = 100000;
int N, H, U;

typedef struct{
	int height;
	int weight;
} fruit;

int compare_fruit(const void* A, const void* B)
{
	const fruit *a = A;
	const fruit *b = B;
	
	if (a->weight < b->weight)
		return -1;
	if (a->weight > b->weight)
		return 1;
	if (a->height < b->height)
		return -1;
	if (a->height > b->height)
		return 1;
		
	return 0;
}

int sum(fruit *fr)
{
	int i, s = 0;
	for (i = 0; i < N; i++)
		s += fr[i].weight;
		
	return s;
}

int min_height(fruit *fr)
{
	int i, m = H+1;
	for (i = 0; i < N; i++)
		if (fr[i].height < m)
			m = fr[i].height;
	return m;
}

int solve1(fruit* fr)
{
	/* Se poate rezolva mult mai eficient folosind maxheap */
	if (U == 0)
		return sum(fr);
		
	int i, count = 0;
	int current_height = 0, current_weight = 0;
	int ceil = (H - min_height(fr))/U +1;
	
	qsort(fr, N, sizeof(fruit), compare_fruit);
	
	/* While the current height is smaller than the maximum height and
	 * the number of picked fruits is smaller than N, pick the biggest
	 * apple, set it's weight to '-1', update the other weights;
	 * Complexy: O(H/N * nlong); */
	while ((current_height <= H) && (count < ceil))
	{
		qsort(fr, N, sizeof(fruit), compare_fruit);
		
		for (i = N-1; i >= 0; i--)
			printf("%3d%c", fr[i].weight, (i)? ' ':'\n');
		for (i = N-1; i >= 0; i--)
			printf("%3d%c", fr[i].height, (i)? ' ':'\n');
		 
		if (fr[N-1].weight == -1) break;
		current_weight += fr[N-1].weight;
		current_height += U;
		count++;
		printf("Added apple: w = %d, h = %d, count = %d:%d\n", fr[N-1].weight, fr[N-1].height, count, ceil);
		
		for (i = N-2; i >= 0; i--)
		{
			/* If the fruit taken is from a row of life span 1
			 * eliminate all ellements with life span 1*/
			if ((fr[N-1].height + U >= H) && (fr[i].height + U >= H))
				fr[i].weight = -1;
			
			/* If index height is lesser to current height
			 * shorten life span by 1 */
			if (fr[i].height < fr[N-1].height)
			{
				if ((fr[i].height + U) < H)
					fr[i].height += U;
				else
					fr[i].weight = -1;
			}
		}
		
		fr[N-1].weight = -1;
	}
	
	return current_weight;
}

int solve(fruit* fr)
{
	/* Se poate rezolva mult mai eficient folosind maxheap */
	if (U == 0)
		return sum(fr);
		
	int i, count = 0;
	int current_height = 0, current_weight = 0;
	int ceil = (H - min_height(fr))/U +1;
	
	qsort(fr, N, sizeof(fruit), compare_fruit);
	
	/* While the current height is smaller than the maximum height and
	 * the number of picked fruits is smaller than N, pick the biggest
	 * apple, set it's weight to '-1', update the other weights;
	 * Complexy: O(H/N * nlong); */
	while ((current_height <= H) && (count < ceil))
	{
		/*can do this with dei*/
		 int max_weight = -1;
		 int pos = -1;
		 
		 for (i = 0; i < N; i++)
			if (fr[i].weight > max_weight)
			{
				max_weight = fr[i].weight;
				pos = i;
			}
		
		for (i = N-1; i >= 0; i--)
			printf("%3d%c", fr[i].weight, (i)? ' ':'\n');
		for (i = N-1; i >= 0; i--)
			printf("%3d%c", fr[i].height, (i)? ' ':'\n');
		 
		if (fr[pos].weight == -1) break;
		current_weight += fr[pos].weight;
		current_height += U;
		count++;
		printf("Added apple: w = %d, h = %d, count = %d:%d\n", fr[pos].weight, fr[pos].height, count, ceil);
		
		for (i = N-2; i >= 0; i--)
		{
			/* If the fruit taken is from a row of life span 1
			 * eliminate all ellements with life span 1*/
			if ((fr[pos].height + U >= H) && (fr[i].height + U >= H))
				fr[i].weight = -1;
			
			/* If index height is lesser to current height
			 * shorten life span by 1 */
			if (fr[i].height < fr[pos].height)
			{
				if ((fr[i].height + U) < H)
					fr[i].height += U;
				else
					fr[i].weight = -1;
			}
		}
		
		fr[pos].weight = -1;
	}
	
	return current_weight;
}


int main()
{
	FILE *fin, *fout;
	
	/* Try opening files */
	if (!(fin = fopen(infile, "r"))) 
	{
		fprintf(stderr, "Could not open input file.\n");
		return -1;
	}
	if (!(fout = fopen(outfile, "w"))) 
	{
		fprintf(stderr, "Could not open output file.\n");
		return -1;
	}

	int i, weight;
	
	fscanf(fin, "%d %d %d", &N, &H, &U);
	if (N>NMAX)
	{
		fprintf(stderr, "Count size out of bounds.\n");
		return 1;
	}
	
	fruit* quinces;
	quinces = (fruit*) malloc(N*sizeof(fruit));
	
	for (i = 0; i < N; i++)
		fscanf(fin, "%d %d", &quinces[i].height, &quinces[i].weight);

	weight = solve(quinces);
	
	fprintf(fout, "%d\n", weight);
	
	/* Close files and free memory */
	free(quinces);
	
	fclose(fin);
	fclose(fout);
	
	return 0;
}