Cod sursa(job #676748)

Utilizator lxnchPopescu Ion lxnch Data 9 februarie 2012 16:12:56
Problema Heapuri Scor 40
Compilator c Status done
Runda Arhiva educationala Marime 3.11 kb
#include <stdio.h>
#include <stdlib.h>

const unsigned int maxop = 200000;
const unsigned int maxelem = 1000000000;
unsigned int pozIntrare[200000];
unsigned int nrIntrari;

void afiseaza(unsigned int *heap, unsigned int dim) {
	unsigned int i=0;
	for(;i<dim; i++) {
		printf("%u ", heap[i]);
	}
	printf("\n");
}

void refaHeap(unsigned int *heap, unsigned int start, unsigned int stop){
	unsigned int index=start;
	short int eHeap=0;
	unsigned int temp;

	while((2*index+1 < stop) && !eHeap) {
		unsigned int copil = 2*index+1;
		if ((copil < stop-1) && (heap[copil] > heap[copil+1])) copil++;
		if (heap[index] > heap[copil]) {
			temp = heap[index]; heap[index] = heap[copil]; heap[copil] = temp;
			index = copil;
		}
		else {
			eHeap=1;
		}
	}
}

void insereaza(unsigned int *heap, unsigned int *dim, unsigned int elem) {
	//daca heap-ul e gol, punem elementul ca radacina si incrementam contorul nrelem;
	if (*dim == 0 ) {
		heap[0] =elem;
		*dim+=1;
		pozIntrare[nrIntrari++]=elem;
	}
	else if (*dim < maxelem) {
		*dim+=1; // facem loc pentru noul element
		heap[*dim-1]=elem; //pun elementul de inserat pe ultima pozitie din heap
		pozIntrare[nrIntrari++]=elem;
		int i=(*dim-1)/2;
		//refac heap-ul
		for(;i>=0; i--)
			refaHeap(heap, i, *dim);
	}
	else // am umplut heap-ul
		return;
}

void elimina(unsigned int *heap, unsigned int *dim, unsigned int pozelem) {
	// intai luam elementul care-a fost inserat pe pozitia respectiva
	unsigned int elem = pozIntrare[pozelem-1];
	if(elem == -1) return;
	//afiseaza(heap, *dim);
	//printf("Vrei sa-l elimin pe %u\n", elem);
	//gasesc pozitia in heap a elementului pe care vreau sa-l elimin
	unsigned int i=0;
	for(;i<*dim;i++) {
		if (heap[i] == elem)
			break;
	}
	if (i == *dim-1) return; // nu am gasit
	//printf("De pe pozitia %u in heap!\n", i);
	unsigned int temp;
	temp=heap[*dim-1]; heap[*dim-1]=heap[i]; heap[i]=temp; // swap
	*dim-=1;
	int j=(*dim-1)/2;
	//refac heap-ul
	for(;j>=0; j--)
		refaHeap(heap, j, *dim);
	pozIntrare[pozelem-1]=-1;
	//printf("Eliminat!\n");
	//afiseaza(heap, *dim);
}

int main() {
	//FILE *fisin, *fisout;
	unsigned int c1, c2, nrop, nrelem=0;
	unsigned int heap[100000];
	int l;
	freopen("heapuri.in", "r", stdin);
	freopen("heapuri.out", "w", stdout);

	//if ((fisin = fopen("heapuri.in", "r")) == NULL)
	//exit(1);
	//if ((fisout = fopen("heapuri.out", "w")) == NULL)
//		exit(1);

	scanf("%u", &nrop);
	if (nrop > maxop && 1 <= nrop) // 1<= N<=200.000
		exit(1);

	for(l=1;l<=nrop;l++) {
		scanf("%u", &c1);

		switch (c1) {
		case 1:
			scanf("%u", &c2);
			//inserez elementul c2 in heap
			if (c2 > maxelem)
				exit(1);
			insereaza(heap, &nrelem, c2);
			break;
		case 2:
			scanf("%u", &c2);
			//sterg elementul de pe pozitia specificata de c2
			elimina(heap, &nrelem, c2);
			break;
		case 3:
			//afisez elementul minim din heap, adica radacina
			printf("%u\n", heap[0]);
			break;
		default:
			exit(1);
			break;
		}
	}
	//afiseaza(pozIntrare, nrIntrari);
	//printf("Total elemente: %u\n", nrelem);
	//fclose(fisin);
	//fclose(fisout);
	return 0;
}