Cod sursa(job #439842)

Utilizator BrEacKRazvan Aurariu BrEacK Data 11 aprilie 2010 19:49:46
Problema Gutui Scor 0
Compilator c Status done
Runda teme_upb Marime 5.72 kb
#include<stdio.h>
#include<stdlib.h>

typedef struct Gutuie{
	int gr;
	struct Gutuie* prec;
	struct Gutuie* urm;
}gutuie;

typedef struct Pas{
	int nr;
	struct Gutuie* first;
	struct Pas* urm;
	struct Pas* prec;
}pas;

#define DEBUG 1
int main(int argc, char* argv[]) {
	FILE * fin = fopen("gutui.in","r");
	FILE * fout = fopen("gutui.out","w");
#ifdef DEBUG
	stdin = fin;
	stdout = fout;
#endif
	pas pasi;
	pasi.nr = -1;
	pasi.prec = NULL;
	pasi.urm = NULL;
	pasi.first = NULL;
	pas* ppas, *tmp_ppas;
	gutuie *pgutuie, *tmp_pgutuie;
	int i, j;
	int n, h, u;
	int inaltime, greutate, nr_pasi_max, start, nr_pas, rezolvat, luate, max_gutui, nivel_minim = ~(1 << 31), nivel_maxim_cautare;
	int t_max_gr, t_max_pas;

	fscanf(stdin,"%d %d %d",&n, &h, &u);
	h++;
	nr_pasi_max = (h-1)/u + !(!((h-1)%u));
	//fprintf(stderr, "nr_pasi_max = %d\n", nr_pasi_max);
	start = h%u;

	for(i = 0;i < n; i++) {
		fscanf(stdin,"%d",&inaltime);
		fscanf(stdin,"%d",&greutate);
		//fprintf(stderr, "Am citit inaltime=%d greutate=%d\n",inaltime,greutate);
		if(inaltime < h) {
			nr_pas = (inaltime - start) / u;
			tmp_pgutuie = (gutuie*)malloc(sizeof(gutuie));
			tmp_pgutuie->gr = greutate;
			tmp_pgutuie->prec = NULL;
			tmp_pgutuie->urm = NULL;
			ppas = &pasi;
			rezolvat = 0;
			while(ppas != NULL && !rezolvat) {
				if(nr_pas == ppas->nr) {
					//fprintf(stderr, "Am deja pasul %d\n", nr_pas);
					pgutuie = ppas->first;
					if(ppas->first == NULL) {
						if(nivel_minim > nr_pas) {
							nivel_minim = nr_pas;
						}
						ppas->urm->first = tmp_pgutuie;
						//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
						rezolvat = 1;
					}else {
						j = 0;
						while(pgutuie != NULL && (pgutuie->gr >= greutate) && !rezolvat) {
							if((pgutuie->urm != NULL) && (pgutuie->urm->gr <= greutate)) {
								tmp_pgutuie->prec = pgutuie;
								tmp_pgutuie->urm = pgutuie->urm;
								pgutuie->urm->prec = tmp_pgutuie;
								pgutuie->urm = tmp_pgutuie;
								//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
								rezolvat = 1;
							} else if(pgutuie->urm == NULL) {
								pgutuie->urm = tmp_pgutuie;
								pgutuie->urm->prec = pgutuie;
								//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
								rezolvat = 1;
							}
							pgutuie = pgutuie->urm;j++;
						}
						if(pgutuie != NULL && (pgutuie->gr < greutate)) {
							tmp_pgutuie->urm = ppas->first;
							ppas->first = tmp_pgutuie;
							//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
							rezolvat = 1;
						}
					}
				} else if((nr_pas > ppas->nr) && (ppas->urm != NULL) && (nr_pas < ppas->urm->nr)) {
					tmp_ppas = ppas->urm;
					ppas->urm = (pas*)malloc(sizeof(pas));
					ppas->urm->nr = nr_pas;
					ppas->urm->prec = ppas;
					ppas->urm->urm = tmp_ppas;
					ppas->urm->first = tmp_pgutuie;
					//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
					if(nivel_minim > nr_pas) {
						nivel_minim = nr_pas;
					}
					rezolvat = 1;
				} else if((nr_pas > ppas->nr) && (ppas->urm == NULL)) {
					tmp_ppas = NULL;
					ppas->urm = (pas*)malloc(sizeof(pas));
					ppas->urm->nr = nr_pas;
					ppas->urm->prec = ppas;
					ppas->urm->urm = tmp_ppas;
					ppas->urm->first = tmp_pgutuie;
					//fprintf(stderr, "Am adaugat gutuia %d la pasul %d\n", greutate, nr_pas);
					if(nivel_minim > nr_pas) {
						nivel_minim = nr_pas;
					}
					rezolvat = 1;
				}
				ppas = ppas->urm;
			}
		}
	}
	max_gutui = (nr_pasi_max - nivel_minim) < 100000 ?(nr_pasi_max - nivel_minim) : 100000 ;
	luate = 0;
	greutate = 0;
	rezolvat = 0;
#if DEBUG == 1
	fprintf(stderr, "Am creat structurile cu datele citite.\n");
	ppas = pasi.urm;
	while(ppas != NULL) {
		fprintf(stderr,"%d: ",ppas->nr);
		pgutuie = ppas->first;
		while(pgutuie != NULL) {
			fprintf(stderr, "%d ",pgutuie->gr);
			pgutuie = pgutuie->urm;
		}
		fprintf(stderr, "\n");
		ppas = ppas->urm;
	}
	fprintf(stderr, "nivel_minim = %d, max_gutui = %d\n", nivel_minim, max_gutui);
#endif
	nivel_maxim_cautare = (nivel_minim > (nr_pasi_max + luate - max_gutui)) ? nivel_minim : (nr_pasi_max + luate - max_gutui);
	fprintf(stderr, "nivel_maxim_cautare = %d\n", nivel_maxim_cautare);
	while((max_gutui - luate) > 0 && !rezolvat) {
		ppas = pasi.urm;
		t_max_gr = 0;
		t_max_pas = -1;
		while((ppas != NULL) && (nivel_maxim_cautare >= ppas->nr)) {

			fprintf(stderr,"sunt la nivelul %d\n",ppas->nr);

			if(ppas->nr >= nivel_minim) {
				if(ppas->first != NULL && ppas->first->gr > t_max_gr) {
					t_max_gr = ppas->first->gr;
					t_max_pas = ppas->nr;
					tmp_ppas = ppas;
				}
			}
			ppas = ppas->urm;
		}
		if(t_max_pas == -1) {
			rezolvat = 1;
		} else {
			luate++;
			nivel_maxim_cautare = (nivel_minim > (nr_pasi_max + luate - max_gutui)) ? nivel_minim : (nr_pasi_max + luate - max_gutui);
			greutate += t_max_gr;
			tmp_pgutuie = tmp_ppas->first;
			tmp_ppas->first = tmp_pgutuie->urm;
			if(tmp_ppas->first == NULL) {
				if(tmp_ppas->prec == NULL) {
					pasi.urm = tmp_ppas->urm;
					tmp_ppas->urm->prec = NULL;
				} else {
					tmp_ppas->prec->urm = tmp_ppas->urm;
					if(tmp_ppas->urm != NULL) {
						tmp_ppas->urm->prec = tmp_ppas->prec;
					}
				}
			}
			fprintf(stderr, "Am luat gutuia %d de pe nivelul %d\n", tmp_pgutuie->gr,tmp_ppas->nr );
			//free(tmp_ppas->first);
		}

	}

#if DEBUG == 1
	fprintf(stderr, "Am creat structurile cu datele citite.\n");
	ppas = pasi.urm;
	while(ppas != NULL) {
		fprintf(stderr,"%d: ",ppas->nr);
		pgutuie = ppas->first;
		while(pgutuie != NULL) {
			fprintf(stderr, "%d ",pgutuie->gr);
			pgutuie = pgutuie->urm;
		}
		fprintf(stderr, "\n");
		ppas = ppas->urm;
	}
	fprintf(stderr, "nivel_minim = %d, max_gutui = %d\n", nivel_minim, max_gutui);
#endif
	fprintf(stdout,"%d",greutate);
	fclose(fin);
	fclose(fout);
	return 0;
}