Cod sursa(job #676685)

Utilizator lxnchPopescu Ion lxnch Data 9 februarie 2012 15:22:15
Problema Heapuri Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.92 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];
	//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);
	//printf("Eliminat!\n");
	//afiseaza(heap, *dim);
}

int main() {
	FILE *fisin, *fisout;
	unsigned int c1, c2, nrop, nrelem=0;
	unsigned int heap[100000];

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

	fscanf(fisin,"%u", &nrop);
	if (nrop > maxop)
		exit(1);

	while (feof(fisin) == 0) {
		fscanf(fisin,"%u", &c1);

		switch (c1) {
		case 1:
			fscanf(fisin, "%u", &c2);
			//inserez elementul c2 in heap
			insereaza(heap, &nrelem, c2);
			break;
		case 2:
			fscanf(fisin, "%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:
			break;
		}
	}
	//afiseaza(pozIntrare, nrIntrari);
	//printf("Total elemente: %u\n", nrelem);
	fclose(fisin);
	fclose(fisout);

	return 0;
}