Cod sursa(job #436666)

Utilizator copotalex copot Data 8 aprilie 2010 19:20:42
Problema Gutui Scor 0
Compilator c Status done
Runda teme_upb Marime 5.71 kb
#include <stdio.h>
#include <stdlib.h>

typedef struct {
	unsigned long h;
	unsigned long g;
} gutuie;

typedef struct {
  unsigned int i;
  unsigned int nv;
} nivel;

gutuie vg[100000];
unsigned long N, H, U;
nivel niv[100000];
int nivc = 0;
gutuie vsol[100000];

void citeste()
{
	FILE *f = fopen("gutui.in", "rt");
	int i;
	if ( f == NULL )
		return;
		
	fscanf(f, "%ld%ld%ld", &N, &H, &U);
	for (i = 0; i < N; i++) {
		fscanf(f, "%ld%ld", &vg[i].h, &vg[i].g);
	}
	fclose(f);
}

int ncx(gutuie gut)
{
	return gut.g / (( H - gut.h ) / U + 1);
}

int pas(gutuie gut)
{
  return (H - gut.h) / U;
}

int comp1(const void *s1, const void *s2)
{
	return ((gutuie*)s2)->g - ((gutuie*)s1)->g;
	//return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}

int comp2(const void *s1, const void *s2)
{
	//return ((gutuie*)s2)->h - ((gutuie*)s1)->h;
	return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}

int comp3(const void *s1, const void *s2)
{
	return ( H - ((gutuie*)s1)->h ) / U - ( H - ((gutuie*)s2)->h ) / U;
	//return (float) ((gutuie*)s2)->g / ((gutuie*)s2)->h - (float) ((gutuie*)s1)->g / ((gutuie*)s1)->h;
}

int comp4(const void *s1, const void *s2)
{
	return ((gutuie*)s2)->h - ((gutuie*)s1)->h;
}

int comp5(const void *s1, const void *s2)
{
	return ((gutuie*)s2)->g / (( H - ((gutuie*)s2)->h ) / U+1) - ((gutuie*)s1)->g / (( H - ((gutuie*)s1)->h ) / U+1);
	//return ((gutuie*)s2)->g / 2 ;//( H - ((gutuie*)s2)->h ) / U ;
	
		  // ((gutuie*)s1)->g / ( H - ((gutuie*)s1)->h ) / U;
}

int comp6(const void *s1, const void *s2)
{
	return *(int*)s2 - *(int*)s1;
}

int main(int argc, char **argv)
{
	unsigned long maxg, sol;
	unsigned long i, j, ncmax, ncmin, im, nci, alese, mnext, sg;
	
	citeste();

	qsort(vg, N, sizeof(gutuie), comp3); 

	i = 0;
	nci = 0;
	while (i < N) {
	  while ( pas(vg[i]) != nci )
		nci++;
	  if ( pas(vg[i]) == nci ) {
		niv[nivc].nv = pas(vg[i]);
		niv[nivc].i = i;
		nivc++;
	  }
	  while ( pas(vg[i]) == nci )
		i++;
	  nci++;
	  //i++;
	}
	ncmax = pas(vg[N-1]);
	sol = 0;	
	for (i = 0; i < N; i++)
		printf("%ld %ld -> %ld\n", vg[i].h, vg[i].g, pas(vg[i]));
	printf("\n");
	for (i = 0; i < nivc; i++)
		printf("%ld -> %ld\n", niv[i].i, niv[i].nv);
/*
	alese = 0;
	sol = 0;
	for (i = 0; i < N; i++) {
	  if ( vg[i].h + alese * U > H )
		break;
	  sol += vg[i].g;
	  
	  alese++;
	}
	
	ncmax = sol;
	qsort(vg, N, sizeof(gutuie), comp4); 
	

	alese = 0;
	sol = 0;
	for (i = 0; i < N; i++) {
	  if ( vg[i].h + alese * U > H )
		break;
	  sol += vg[i].g;
	  
	  alese++;
	}
	if ( sol > ncmax )
		ncmax = sol;
	
*/
/*
	nci = N;
	alese = 0;
	ncmin = 1 << 32 - 1;
	mnext = 0;
	ncmin = 1;
	while ( nci > 0 ) {

	  printf("caut %d\n", ncmin);
	  // caut gutui cu nc egal cu ncmin si aleg pe cele cu g max
	  maxg = 0;
	  im = -1;
	  for (i = 0; i < N; i++)
		if ( !vg[i].used && vg[i].g > maxg && (H - vg[i].h) / U + 1 == ncmin ) {
		  maxg = vg[i].g;
		  im = i;
		}
	  if ( im == -1 )
		break;
	  vg[im].used = 1;
	  alese++;
	  for (i = 0; i < N; i++)
		if ( !vg[i].used && vg[i].g > maxg && (H - vg[i].h) / U + 1 > ncmin &&  ncmax   <  (H - vg[i].h) / U + alese + 1 ) {
			printf("am pierdut %d\n", vg[i].g);
			vg[im].used = 0;
			ncmin++;
			alese--;
			break;
		}
	  if ( vg[im].used ) {
		printf("\tam ales %d \n", vg[im].g);
		sol += vg[im].g;
		
	  }
	  
	  nci--;
	}
*/
/*
	sol = 0;
	i = 0;
	sg = 0;
	for ( im = 1; im <= ncmax; im++ ) {
		maxg = 0;

		
		nci = im;

		while ( i < N && (H - vg[i].h) / U + 1 == nci ) {
		  if ( vg[i].g > maxg )
			maxg = vg[i].g;
		  i++;
		}
		if ( maxg == 0 )
		  continue;
		printf("aleg %ld la %ld\n", maxg, nci);
		
		sg = sg + maxg;

		printf("\n");
	}
	sol = sg;*/
/*
	sol = vg[0].g;
	sg = vg[0].g / ((H - vg[0].h) / U+1);
	i = 1;
	printf("aleg %d\n", vg[0].g);
	while ( i < N ) {
	  if ( vg[i].g / ((H - vg[i].h) / U +1)< sg ) {
		sg = vg[i].g / ((H - vg[i].h) / U+1);
		sol = sol + vg[i].g;
		printf("aleg %d\n", vg[i].g);
	  }
	  i++;
	  
	}*/
/*
	sol = 0;
	alese = 0;
	for (i = 0; i < N; i++) {
	  if ( vg[i].h + U * alese <= H ) {
		sol += vg[i].g;
		printf("aleg %d\n", vg[i].g);
		alese++;
		for (j = i + 1; j < N; j++)
		  if ( vg[j].g > vg[i].g && vg[j].h + U * alese > H ) {
			sol -= vg[i].g;
			printf("elimin %d din cauza %d\n", vg[i].g, vg[j].g);
			alese--;
			break;
		  }
	  }
	}*/
/*
	sol = 0;
	alese = 0;
	for (i = 0; i < N; i++) {
	  if ( vg[i].h + U * alese <= H ) {
		sol += vg[i].g;
		alese++;
	  }
	}*/
	int o;
  unsigned long smax = 0;
  for (o = 0; o < N; o++) {

  
	sol = 0;
	nci = niv[0].nv;
	alese = 0;
	maxg = 0;
	i = 0;
	int k;
	im = 0;
	while ( im < nivc ) {

	  nci = niv[im].nv; 
	  if ( nci == pas(vg[N-1]) ) {
		j = N;
	  } else {
		
		j = niv[im+1].i;
		
	  }
	  
	  ncmax = nci + 1 - alese;
	  printf("la nivelul %d iau cel mult  %d gutui\n", nci, ncmax);
	 
	  sg = 0;
	  if ( j - i < ncmax )
		ncmax = j - i;
	  while ( i < j ) {
		printf("\tsol %d\n", vg[i].g );
		if ( i == o )
		  i++;
		vsol[sg].g = vg[i].g;
		vsol[sg++].h = vg[i++].h;
	  }
	  
	  qsort(vsol, sg, sizeof(gutuie), comp1);
	  sg = 0;
	  printf("max = %d\n", ncmax);
	  while ( sg < ncmax ) {
		j = N - 1;
		while ( j > i ) {
		  if ( vg[j].g > vsol[sg].g && vg[j].h + (  alese + j - i  )*U > H )
			break;
		  j--;
		}
		printf("i = %d, alese = %d, j = %d, h = %d\n", i, alese, j, vg[j].h + (alese + j - i  )*U);
		if ( vsol[sg].h + alese * U <= H && j == i ||
			 vsol[sg].h + alese * U <= H && nci == pas(vg[N-1]) ) {
		  printf("\tam ales %d\n", vsol[sg].g);
		  sol += vsol[sg++].g;
		  alese++;
		} else {
		  printf("\tnu aleg %d din cazula la %d\n", vsol[sg].g, vg[j].g);
		  sg++;
		}
	  }
		
	  im++;
	}
	if ( sol > smax )
		smax = sol;
	printf("SOL: %ld\n", sol);
  }
	
	FILE *f = fopen("gutui.out", "wt");
	fprintf(f, "%ld\n", smax);
	fclose(f);
	
	return 0;
}